#
# This file contains implementations of the LLDB display panes in VIM
#
# The most generic way to define a new window is to inherit from VimPane
# and to implement:
# - get_content() - returns a string with the pane contents
#
# Optionally, to highlight text, implement:
# - get_highlights() - returns a map 
# 
# And call:
# - define_highlight(unique_name, colour)
# at some point in the constructor.
#
#
# If the pane shows some key-value data that is in the context of a
# single frame, inherit from FrameKeyValuePane and implement:
# - get_frame_content(self, SBFrame frame)
# 
#
# If the pane presents some information that can be retrieved with
# a simple LLDB command while the subprocess is stopped, inherit
# from StoppedCommandPane and call:
# - self.setCommand(command, command_args)
# at some point in the constructor.
#
# Optionally, you can implement:
# - get_selected_line()
# to highlight a selected line and place the cursor there.
# 
#
# FIXME: implement WatchlistPane to displayed watched expressions
# FIXME: define interface for interactive panes, like catching enter 
#        presses to change selected frame/thread...
# 

import lldb
import vim

import sys

# ==============================================================
# Get the description of an lldb object or None if not available
# ==============================================================

# Shamelessly copy/pasted from lldbutil.py in the test suite
def get_description(obj, option=None):
    """Calls lldb_obj.GetDescription() and returns a string, or None.

    For SBTarget, SBBreakpointLocation, and SBWatchpoint lldb objects, an extra
    option can be passed in to describe the detailed level of description
    desired:
        o lldb.eDescriptionLevelBrief
        o lldb.eDescriptionLevelFull
        o lldb.eDescriptionLevelVerbose
    """
    method = getattr(obj, 'GetDescription')
    if not method:
        return None
    tuple = (lldb.SBTarget, lldb.SBBreakpointLocation, lldb.SBWatchpoint)
    if isinstance(obj, tuple):
        if option is None:
            option = lldb.eDescriptionLevelBrief

    stream = lldb.SBStream()
    if option is None:
        success = method(stream)
    else:
        success = method(stream, option)
    if not success:
        return None
    return stream.GetData()
 
def get_selected_thread(target):
  """ Returns a tuple with (thread, error) where thread == None if error occurs """
  process = target.GetProcess()
  if process is None or not process.IsValid():
    return (None, VimPane.MSG_NO_PROCESS)

  thread = process.GetSelectedThread()
  if thread is None or not thread.IsValid():
    return (None, VimPane.MSG_NO_THREADS)
  return (thread, "")

def get_selected_frame(target):
  """ Returns a tuple with (frame, error) where frame == None if error occurs """
  (thread, error) = get_selected_thread(target)
  if thread is None:
    return (None, error)

  frame = thread.GetSelectedFrame()
  if frame is None or not frame.IsValid():
    return (None, VimPane.MSG_NO_FRAME)
  return (frame, "")

def _cmd(cmd):
  vim.command("call confirm('%s')" % cmd)
  vim.command(cmd)

def move_cursor(line, col=0):
  """ moves cursor to specified line and col """
  cw = vim.current.window
  if cw.cursor[0] != line:
    vim.command("execute \"normal %dgg\"" % line)

def winnr():
  """ Returns currently selected window number """
  return int(vim.eval("winnr()"))

def bufwinnr(name):
  """ Returns window number corresponding with buffer name """
  return int(vim.eval("bufwinnr('%s')" % name))

def goto_window(nr):
  """ go to window number nr"""
  if nr != winnr():
    vim.command(str(nr) + ' wincmd w')

def goto_next_window():
  """ go to next window. """
  vim.command('wincmd w')
  return (winnr(), vim.current.buffer.name)

def goto_previous_window():
  """ go to previously selected window """
  vim.command("execute \"normal \\<c-w>p\"")

def have_gui():
  """ Returns True if vim is in a gui (Gvim/MacVim), False otherwise. """
  return int(vim.eval("has('gui_running')")) == 1

class PaneLayout(object):
  """ A container for a (vertical) group layout of VimPanes """

  def __init__(self):
    self.panes = {}

  def havePane(self, name):
    """ Returns true if name is a registered pane, False otherwise """
    return name in self.panes

  def prepare(self, panes = []):
    """ Draw panes on screen. If empty list is provided, show all. """

    # If we can't select a window contained in the layout, we are doing a first draw
    first_draw = not self.selectWindow(True)
    did_first_draw = False

    # Prepare each registered pane
    for name in self.panes:
      if name in panes or len(panes) == 0:
        if first_draw:
          # First window in layout will be created with :vsp, and closed later
          vim.command(":vsp")
          first_draw = False
          did_first_draw = True
        self.panes[name].prepare()

    if did_first_draw:
      # Close the split window
      vim.command(":q")

    self.selectWindow(False)

  def contains(self, bufferName = None):
    """ Returns True if window with name bufferName is contained in the layout, False otherwise.
        If bufferName is None, the currently selected window is checked.
    """
    if not bufferName:
      bufferName = vim.current.buffer.name

    for p in self.panes:
      if bufferName is not None and bufferName.endswith(p):
        return True
    return False

  def selectWindow(self, select_contained = True):
    """ Selects a window contained in the layout (if select_contained = True) and returns True.
        If select_contained = False, a window that is not contained is selected. Returns False
        if no group windows can be selected.
    """
    if select_contained == self.contains():
      # Simple case: we are already selected
      return True

    # Otherwise, switch to next window until we find a contained window, or reach the first window again.
    first = winnr()
    (curnum, curname) = goto_next_window()

    while not select_contained == self.contains(curname) and curnum != first:
      (curnum, curname) = goto_next_window()

    return self.contains(curname) == select_contained

  def hide(self, panes = []):
    """ Hide panes specified. If empty list provided, hide all. """
    for name in self.panes:
      if name in panes or len(panes) == 0:
        self.panes[name].destroy()

  def registerForUpdates(self, p):
    self.panes[p.name] = p

  def update(self, target, controller):
    for name in self.panes:
      self.panes[name].update(target, controller)


class VimPane(object):
  """ A generic base class for a pane that displays stuff """
  CHANGED_VALUE_HIGHLIGHT_NAME_GUI = 'ColorColumn'
  CHANGED_VALUE_HIGHLIGHT_NAME_TERM = 'lldb_changed'
  CHANGED_VALUE_HIGHLIGHT_COLOUR_TERM = 'darkred'

  SELECTED_HIGHLIGHT_NAME_GUI = 'Cursor'
  SELECTED_HIGHLIGHT_NAME_TERM = 'lldb_selected'
  SELECTED_HIGHLIGHT_COLOUR_TERM = 'darkblue'

  MSG_NO_TARGET = "Target does not exist."
  MSG_NO_PROCESS = "Process does not exist."
  MSG_NO_THREADS = "No valid threads."
  MSG_NO_FRAME = "No valid frame."

  # list of defined highlights, so we avoid re-defining them
  highlightTypes = []

  def __init__(self, owner, name, open_below=False, height=3):
    self.owner = owner
    self.name = name
    self.buffer = None
    self.maxHeight = 20
    self.openBelow = open_below
    self.height = height
    self.owner.registerForUpdates(self)

  def isPrepared(self):
    """ check window is OK """
    if self.buffer == None or len(dir(self.buffer)) == 0 or bufwinnr(self.name) == -1:
      return False
    return True

  def prepare(self, method = 'new'):
    """ check window is OK, if not then create """
    if not self.isPrepared():
      self.create(method)

  def on_create(self):
    pass

  def destroy(self):
    """ destroy window """
    if self.buffer == None or len(dir(self.buffer)) == 0:
      return
    vim.command('bdelete ' + self.name)

  def create(self, method):
    """ create window """

    if method != 'edit':
      belowcmd = "below" if self.openBelow else ""
      vim.command('silent %s %s %s' % (belowcmd, method, self.name))
    else:
      vim.command('silent %s %s' % (method, self.name))

    self.window = vim.current.window
  
    # Set LLDB pane options
    vim.command("setlocal buftype=nofile") # Don't try to open a file
    vim.command("setlocal noswapfile")     # Don't use a swap file
    vim.command("set nonumber")            # Don't display line numbers
    #vim.command("set nowrap")              # Don't wrap text

    # Save some parameters and reference to buffer
    self.buffer = vim.current.buffer
    self.width  = int( vim.eval("winwidth(0)")  )
    self.height = int( vim.eval("winheight(0)") )

    self.on_create()
    goto_previous_window()

  def update(self, target, controller):
    """ updates buffer contents """
    self.target = target
    if not self.isPrepared():
      # Window is hidden, or otherwise not ready for an update
      return

    original_cursor = self.window.cursor

    # Select pane
    goto_window(bufwinnr(self.name))

    # Clean and update content, and apply any highlights.
    self.clean()

    if self.write(self.get_content(target, controller)):
      self.apply_highlights()

      cursor = self.get_selected_line()
      if cursor is None:
        # Place the cursor at its original position in the window
        cursor_line = min(original_cursor[0], len(self.buffer))
        cursor_col = min(original_cursor[1], len(self.buffer[cursor_line - 1]))
      else:
        # Place the cursor at the location requested by a VimPane implementation
        cursor_line = min(cursor, len(self.buffer))
        cursor_col = self.window.cursor[1]

      self.window.cursor = (cursor_line, cursor_col)

    goto_previous_window()

  def get_selected_line(self):
    """ Returns the line number to move the cursor to, or None to leave
        it where the user last left it.
        Subclasses implement this to define custom behaviour.
    """
    return None

  def apply_highlights(self):
    """ Highlights each set of lines in  each highlight group """
    highlights = self.get_highlights()
    for highlightType in highlights:
      lines = highlights[highlightType]
      if len(lines) == 0:
        continue

      cmd = 'match %s /' % highlightType
      lines = ['\%' + '%d' % line + 'l' for line in lines]
      cmd += '\\|'.join(lines)
      cmd += '/'
      vim.command(cmd)

  def define_highlight(self, name, colour):
    """ Defines highlihght """
    if name in VimPane.highlightTypes:
      # highlight already defined
      return

    vim.command("highlight %s ctermbg=%s guibg=%s" % (name, colour, colour))
    VimPane.highlightTypes.append(name)

  def write(self, msg):
    """ replace buffer with msg"""
    self.prepare()

    msg = str(msg.encode("utf-8", "replace")).split('\n')
    try:
      self.buffer.append(msg)
      vim.command("execute \"normal ggdd\"")
    except vim.error:
      # cannot update window; happens when vim is exiting.
      return False

    move_cursor(1, 0)
    return True

  def clean(self):
    """ clean all datas in buffer """
    self.prepare()
    vim.command(':%d')
    #self.buffer[:] = None

  def get_content(self, target, controller):
    """ subclasses implement this to provide pane content """
    assert(0 and "pane subclass must implement this")
    pass

  def get_highlights(self):
    """ Subclasses implement this to provide pane highlights.
        This function is expected to return a map of:
          { highlight_name ==> [line_number, ...], ... }
    """
    return {}


class FrameKeyValuePane(VimPane):
  def __init__(self, owner, name, open_below):
    """ Initialize parent, define member variables, choose which highlight
        to use based on whether or not we have a gui (MacVim/Gvim).
    """

    VimPane.__init__(self, owner, name, open_below)

    # Map-of-maps key/value history { frame --> { variable_name, variable_value } }
    self.frameValues = {}

    if have_gui():
      self.changedHighlight = VimPane.CHANGED_VALUE_HIGHLIGHT_NAME_GUI
    else:
      self.changedHighlight = VimPane.CHANGED_VALUE_HIGHLIGHT_NAME_TERM
      self.define_highlight(VimPane.CHANGED_VALUE_HIGHLIGHT_NAME_TERM,
                            VimPane.CHANGED_VALUE_HIGHLIGHT_COLOUR_TERM)
 
  def format_pair(self, key, value, changed = False):
    """ Formats a key/value pair. Appends a '*' if changed == True """
    marker = '*' if changed else ' '
    return "%s %s = %s\n" % (marker, key, value)

  def get_content(self, target, controller):
    """ Get content for a frame-aware pane. Also builds the list of lines that
        need highlighting (i.e. changed values.)
    """
    if target is None or not target.IsValid():
      return VimPane.MSG_NO_TARGET

    self.changedLines = []

    (frame, err) = get_selected_frame(target)
    if frame is None:
      return err

    output = get_description(frame)
    lineNum = 1

    # Retrieve the last values displayed for this frame
    frameId = get_description(frame.GetBlock())
    if frameId in self.frameValues:
      frameOldValues = self.frameValues[frameId]
    else:
      frameOldValues = {}

    # Read the frame variables
    vals = self.get_frame_content(frame)
    for (key, value) in vals:
      lineNum += 1
      if len(frameOldValues) == 0 or (key in frameOldValues and frameOldValues[key] == value):
        output += self.format_pair(key, value)
      else:
        output += self.format_pair(key, value, True)
        self.changedLines.append(lineNum)
      
    # Save values as oldValues
    newValues = {}
    for (key, value) in vals:
      newValues[key] = value
    self.frameValues[frameId] = newValues

    return output

  def get_highlights(self):
    ret = {}
    ret[self.changedHighlight] = self.changedLines
    return ret

class LocalsPane(FrameKeyValuePane):
  """ Pane that displays local variables """
  def __init__(self, owner, name = 'locals'):
    FrameKeyValuePane.__init__(self, owner, name, open_below=True)
    
    # FIXME: allow users to customize display of args/locals/statics/scope
    self.arguments = True
    self.show_locals = True
    self.show_statics = True
    self.show_in_scope_only = True

  def format_variable(self, var):
    """ Returns a Tuple of strings "(Type) Name", "Value" for SBValue var """
    val = var.GetValue()
    if val is None:
      # If the value is too big, SBValue.GetValue() returns None; replace with ...
      val = "..."

    return ("(%s) %s" % (var.GetTypeName(), var.GetName()), "%s" % val)

  def get_frame_content(self, frame):
    """ Returns list of key-value pairs of local variables in frame """
    vals = frame.GetVariables(self.arguments,
                                   self.show_locals,
                                   self.show_statics,
                                   self.show_in_scope_only)
    return [self.format_variable(x) for x in vals]

class RegistersPane(FrameKeyValuePane):
  """ Pane that displays the contents of registers """
  def __init__(self, owner, name = 'registers'):
    FrameKeyValuePane.__init__(self, owner, name, open_below=True)

  def format_register(self, reg):
    """ Returns a tuple of strings ("name", "value") for SBRegister reg. """
    name = reg.GetName()
    val = reg.GetValue()
    if val is None:
      val = "..."
    return (name, val.strip())

  def get_frame_content(self, frame):
    """ Returns a list of key-value pairs ("name", "value") of registers in frame """

    result = []
    for register_sets in frame.GetRegisters():
      # hack the register group name into the list of registers...
      result.append((" = = %s =" % register_sets.GetName(), ""))

      for reg in register_sets:
        result.append(self.format_register(reg))
    return result

class CommandPane(VimPane):
  """ Pane that displays the output of an LLDB command """
  def __init__(self, owner, name, open_below, process_required=True):
    VimPane.__init__(self, owner, name, open_below)
    self.process_required = process_required

  def setCommand(self, command, args = ""):
    self.command = command
    self.args = args

  def get_content(self, target, controller):
    output = ""
    if not target:
      output = VimPane.MSG_NO_TARGET
    elif self.process_required and not target.GetProcess():
      output = VimPane.MSG_NO_PROCESS
    else:
      (success, output) = controller.getCommandOutput(self.command, self.args)
    return output

class StoppedCommandPane(CommandPane):
  """ Pane that displays the output of an LLDB command when the process is
      stopped; otherwise displays process status. This class also implements
      highlighting for a single line (to show a single-line selected entity.)
  """
  def __init__(self, owner, name, open_below):
    """ Initialize parent and define highlight to use for selected line. """
    CommandPane.__init__(self, owner, name, open_below)
    if have_gui():
      self.selectedHighlight = VimPane.SELECTED_HIGHLIGHT_NAME_GUI
    else:
      self.selectedHighlight = VimPane.SELECTED_HIGHLIGHT_NAME_TERM
      self.define_highlight(VimPane.SELECTED_HIGHLIGHT_NAME_TERM,
                            VimPane.SELECTED_HIGHLIGHT_COLOUR_TERM)
 
  def get_content(self, target, controller):
    """ Returns the output of a command that relies on the process being stopped.
        If the process is not in 'stopped' state, the process status is returned.
    """
    output = ""
    if not target or not target.IsValid():
      output = VimPane.MSG_NO_TARGET
    elif not target.GetProcess() or not target.GetProcess().IsValid():
      output = VimPane.MSG_NO_PROCESS
    elif target.GetProcess().GetState() == lldb.eStateStopped:
      (success, output) = controller.getCommandOutput(self.command, self.args)
    else:
      (success, output) = controller.getCommandOutput("process", "status")
    return output

  def get_highlights(self):
    """ Highlight the line under the cursor. Users moving the cursor has
        no effect on the selected line.
    """
    ret = {}
    line = self.get_selected_line()
    if line is not None:
      ret[self.selectedHighlight] = [line]
      return ret
    return ret

  def get_selected_line(self):
    """ Subclasses implement this to control where the cursor (and selected highlight)
        is placed.
    """
    return None

class DisassemblyPane(CommandPane):
  """ Pane that displays disassembly around PC """
  def __init__(self, owner, name = 'disassembly'):
    CommandPane.__init__(self, owner, name, open_below=True)

    # FIXME: let users customize the number of instructions to disassemble
    self.setCommand("disassemble", "-c %d -p" % self.maxHeight)

class ThreadPane(StoppedCommandPane):
  """ Pane that displays threads list """
  def __init__(self, owner, name = 'threads'):
    StoppedCommandPane.__init__(self, owner, name, open_below=False)
    self.setCommand("thread", "list")

# FIXME: the function below assumes threads are listed in sequential order,
#        which turns out to not be the case. Highlighting of selected thread
#        will be disabled until this can be fixed. LLDB prints a '*' anyways
#        beside the selected thread, so this is not too big of a problem.
#  def get_selected_line(self):
#    """ Place the cursor on the line with the selected entity.
#        Subclasses should override this to customize selection.
#        Formula: selected_line = selected_thread_id + 1
#    """
#    (thread, err) = get_selected_thread(self.target)
#    if thread is None:
#      return None
#    else:
#      return thread.GetIndexID() + 1

class BacktracePane(StoppedCommandPane):
  """ Pane that displays backtrace """
  def __init__(self, owner, name = 'backtrace'):
    StoppedCommandPane.__init__(self, owner, name, open_below=False)
    self.setCommand("bt", "")


  def get_selected_line(self):
    """ Returns the line number in the buffer with the selected frame. 
        Formula: selected_line = selected_frame_id + 2
        FIXME: the above formula hack does not work when the function return
               value is printed in the bt window; the wrong line is highlighted.
    """

    (frame, err) = get_selected_frame(self.target)
    if frame is None:
      return None
    else:
      return frame.GetFrameID() + 2

class BreakpointsPane(CommandPane):
  def __init__(self, owner, name = 'breakpoints'):
    super(BreakpointsPane, self).__init__(owner, name, open_below=False, process_required=False)
    self.setCommand("breakpoint", "list")
