# -*- coding: utf-8 -*-
# This file is part of Eigen, a lightweight C++ template library
# for linear algebra.
#
# Copyright (C) 2009 Benjamin Schindler <bschindler@inf.ethz.ch>
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0

# Pretty printers for Eigen::Matrix
# This is still pretty basic as the python extension to gdb is still pretty basic. 
# It cannot handle complex eigen types and it doesn't support many of the other eigen types
# This code supports fixed size as well as dynamic size matrices

# To use it:
#
# * Create a directory and put the file as well as an empty __init__.py in 
#   that directory.
# * Create a ~/.gdbinit file, that contains the following:
#      python
#      import sys
#      sys.path.insert(0, '/path/to/eigen/printer/directory')
#      from printers import register_eigen_printers
#      register_eigen_printers(None)
#      end

import gdb
import re
from bisect import bisect_left


# Basic row/column iteration code for use with Sparse and Dense matrices
class _MatrixEntryIterator(object):
	
	def __init__(self, rows, cols, row_major):
		self.rows = rows
		self.cols = cols
		self.currentRow = 0
		self.currentCol = 0
		self.rowMajor = row_major

	def __iter__(self):
		return self

	def next(self):
		return self.__next__()  # Python 2.x compatibility

	def __next__(self):
		row = self.currentRow
		col = self.currentCol
		if self.rowMajor == 0:
			if self.currentCol >= self.cols:
				raise StopIteration
				
			self.currentRow += 1
			if self.currentRow >= self.rows:
				self.currentRow = 0
				self.currentCol += 1
		else:
			if self.currentRow >= self.rows:
				raise StopIteration
				
			self.currentCol += 1
			if self.currentCol >= self.cols:
				self.currentCol = 0
				self.currentRow += 1

		return row, col


class EigenMatrixPrinter:
	"""Print Eigen Matrix or Array of some kind"""

	def __init__(self, variety, val):
		"""Extract all the necessary information"""
		
		# Save the variety (presumably "Matrix" or "Array") for later usage
		self.variety = variety
		
		# The gdb extension does not support value template arguments - need to extract them by hand
		typeinfo = val.type
		if typeinfo.code == gdb.TYPE_CODE_REF:
			typeinfo = typeinfo.target()
		self.type = typeinfo.unqualified().strip_typedefs()
		tag = self.type.tag
		regex = re.compile('<.*>')
		m = regex.findall(tag)[0][1:-1]
		template_params = m.split(',')
		template_params = [x.replace(" ", "") for x in template_params]
		
		if template_params[1] in ['-0x00000000000000001', '-0x000000001', '-1']:
			self.rows = val['m_storage']['m_rows']
		else:
			self.rows = int(template_params[1])
		
		if template_params[2] in ['-0x00000000000000001', '-0x000000001', '-1']:
			self.cols = val['m_storage']['m_cols']
		else:
			self.cols = int(template_params[2])
		
		self.options = 0  # default value
		if len(template_params) > 3:
			self.options = template_params[3]
		
		self.rowMajor = (int(self.options) & 0x1)
		
		self.innerType = self.type.template_argument(0)
		
		self.val = val
		
		# Fixed size matrices have a struct as their storage, so we need to walk through this
		self.data = self.val['m_storage']['m_data']
		if self.data.type.code == gdb.TYPE_CODE_STRUCT:
			self.data = self.data['array']
			self.data = self.data.cast(self.innerType.pointer())
			
	class _Iterator(_MatrixEntryIterator):
		def __init__(self, rows, cols, data_ptr, row_major):
			super(EigenMatrixPrinter._Iterator, self).__init__(rows, cols, row_major)

			self.dataPtr = data_ptr

		def __next__(self):
			row, col = super(EigenMatrixPrinter._Iterator, self).__next__()
			
			item = self.dataPtr.dereference()
			self.dataPtr += 1
			if self.cols == 1:  # if it's a column vector
				return '[%d]' % (row,), item
			elif self.rows == 1:  # if it's a row vector
				return '[%d]' % (col,), item
			return '[%d,%d]' % (row, col), item
			
	def children(self):
		return self._Iterator(self.rows, self.cols, self.data, self.rowMajor)
		
	def to_string(self):
		return "Eigen::%s<%s,%d,%d,%s> (data ptr: %s)" % (
			self.variety, self.innerType, self.rows, self.cols,
			"RowMajor" if self.rowMajor else "ColMajor", self.data)


class EigenSparseMatrixPrinter:
	"""Print an Eigen SparseMatrix"""

	def __init__(self, val):
		"""Extract all the necessary information"""

		typeinfo = val.type
		if typeinfo.code == gdb.TYPE_CODE_REF:
			typeinfo = typeinfo.target()
		self.type = typeinfo.unqualified().strip_typedefs()
		tag = self.type.tag
		regex = re.compile('<.*>')
		m = regex.findall(tag)[0][1:-1]
		template_params = m.split(',')
		template_params = [x.replace(" ", "") for x in template_params]

		self.options = 0
		if len(template_params) > 1:
			self.options = template_params[1]
		
		self.rowMajor = (int(self.options) & 0x1)
		
		self.innerType = self.type.template_argument(0)
		
		self.val = val

		self.data = self.val['m_data']
		self.data = self.data.cast(self.innerType.pointer())

	class _Iterator(_MatrixEntryIterator):
		def __init__(self, rows, cols, val, row_major):
			super(EigenSparseMatrixPrinter._Iterator, self).__init__(rows, cols, row_major)

			self.val = val
			
		def __next__(self):
			row, col = super(EigenSparseMatrixPrinter._Iterator, self).__next__()
				
			# repeat calculations from SparseMatrix.h:
			outer = row if self.rowMajor else col
			inner = col if self.rowMajor else row
			start = self.val['m_outerIndex'][outer]
			end = (
				(start + self.val['m_innerNonZeros'][outer])
				if self.val['m_innerNonZeros'] else self.val['m_outerIndex'][outer+1]
			)

			# and from CompressedStorage.h:
			data = self.val['m_data']
			if start >= end:
				item = 0
			elif (end > start) and (inner == data['m_indices'][end-1]):
				item = data['m_values'][end-1]
			else:
				# create Python index list from the target range within m_indices
				indices = [data['m_indices'][x] for x in range(int(start), int(end)-1)]
				# find the index with binary search
				idx = int(start) + bisect_left(indices, inner)
				if idx < end and data['m_indices'][idx] == inner:
					item = data['m_values'][idx]
				else:
					item = 0

			return '[%d,%d]' % (row, col), item

	def children(self):
		if self.data:
			return self._Iterator(self.rows(), self.cols(), self.val, self.rowMajor)

		return iter([])   # empty matrix, for now

	def rows(self):
		return self.val['m_outerSize'] if self.rowMajor else self.val['m_innerSize']

	def cols(self):
		return self.val['m_innerSize'] if self.rowMajor else self.val['m_outerSize']

	def to_string(self):

		if self.data:
			status = ("not compressed" if self.val['m_innerNonZeros'] else "compressed")
		else:
			status = "empty"
		dimensions = "%d x %d" % (self.rows(), self.cols())
		layout = "row" if self.rowMajor else "column"

		return "Eigen::SparseMatrix<%s>, %s, %s major, %s" % (
			self.innerType, dimensions, layout, status)


class EigenQuaternionPrinter:
	"""Print an Eigen Quaternion"""
	
	def __init__(self, val):
		"""Extract all the necessary information"""
		# The gdb extension does not support value template arguments - need to extract them by hand
		typeinfo = val.type
		if typeinfo.code == gdb.TYPE_CODE_REF:
			typeinfo = typeinfo.target()
		self.type = typeinfo.unqualified().strip_typedefs()
		self.innerType = self.type.template_argument(0)
		self.val = val
		
		# Quaternions have a struct as their storage, so we need to walk through this
		self.data = self.val['m_coeffs']['m_storage']['m_data']['array']
		self.data = self.data.cast(self.innerType.pointer())
			
	class _Iterator:
		def __init__(self, data_ptr):
			self.dataPtr = data_ptr
			self.currentElement = 0
			self.elementNames = ['x', 'y', 'z', 'w']
			
		def __iter__(self):
			return self
	
		def next(self):
			return self.__next__()  # Python 2.x compatibility

		def __next__(self):
			element = self.currentElement
			
			if self.currentElement >= 4:  # there are 4 elements in a quaternion
				raise StopIteration
			
			self.currentElement += 1
			
			item = self.dataPtr.dereference()
			self.dataPtr += 1
			return '[%s]' % (self.elementNames[element],), item
			
	def children(self):
		return self._Iterator(self.data)
	
	def to_string(self):
		return "Eigen::Quaternion<%s> (data ptr: %s)" % (self.innerType, self.data)


def cast_eigen_block_to_matrix(val):
	# Get the type of the variable (and convert to a string)
	# Example: 'const Eigen::Block<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1>, -1, -1, false> const, -1, -1, false>'
	val_type = str(val.type)

	# Extract the Eigen::Matrix type from the Block:
	# From the previous example: Eigen::Matrix<double, -1, -1, 0, -1, -1>
	begin = val_type.find('Eigen::Matrix<')
	end = val_type.find('>', begin) + 1

	# Convert the Eigen::Block to an Eigen::Matrix
	return val.cast(gdb.lookup_type(val_type[begin:end]))


def build_eigen_dictionary():
	pretty_printers_dict[re.compile('^Eigen::Quaternion<.*>$')] = lambda val: EigenQuaternionPrinter(val)
	pretty_printers_dict[re.compile('^Eigen::Matrix<.*>$')] = lambda val: EigenMatrixPrinter("Matrix", val)
	pretty_printers_dict[re.compile('^Eigen::Block<.*>$')] =\
		lambda val: EigenMatrixPrinter("Matrix", cast_eigen_block_to_matrix(val))
	pretty_printers_dict[re.compile('^Eigen::VectorBlock<.*>$')] =\
		lambda val: EigenMatrixPrinter("Matrix", cast_eigen_block_to_matrix(val))
	pretty_printers_dict[re.compile('^Eigen::SparseMatrix<.*>$')] = lambda val: EigenSparseMatrixPrinter(val)
	pretty_printers_dict[re.compile('^Eigen::Array<.*>$')] = lambda val: EigenMatrixPrinter("Array",  val)


def register_eigen_printers(obj):
	"""Register eigen pretty-printers with objfile Obj"""

	if obj is None:
		obj = gdb
	obj.pretty_printers.append(lookup_function)


def lookup_function(val):
	"""Look-up and return a pretty-printer that can print val."""
	
	typeinfo = val.type
	
	if typeinfo.code == gdb.TYPE_CODE_REF:
		typeinfo = typeinfo.target()
	
	typeinfo = typeinfo.unqualified().strip_typedefs()
	
	typename = typeinfo.tag
	if typename is None:
		return None
	
	for function in pretty_printers_dict:
		if function.search(typename):
			return pretty_printers_dict[function](val)
	
	return None


pretty_printers_dict = {}

build_eigen_dictionary()
