# DExTer : Debugging Experience Tester
# ~~~~~~   ~         ~~         ~   ~~
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

from ctypes import *

from . import client
from . import control
from . import symbols
from .probe_process import probe_state
from .utils import *

class STARTUPINFOA(Structure):
  _fields_ = [
      ('cb', c_ulong),
      ('lpReserved', c_char_p),
      ('lpDesktop', c_char_p),
      ('lpTitle', c_char_p),
      ('dwX', c_ulong),
      ('dwY', c_ulong),
      ('dwXSize', c_ulong),
      ('dwYSize', c_ulong),
      ('dwXCountChars', c_ulong),
      ('dwYCountChars', c_ulong),
      ('dwFillAttribute', c_ulong),
      ('wShowWindow', c_ushort),
      ('cbReserved2', c_ushort),
      ('lpReserved2', c_char_p),
      ('hStdInput', c_void_p),
      ('hStdOutput', c_void_p),
      ('hStdError', c_void_p)
    ]

class PROCESS_INFORMATION(Structure):
  _fields_ = [
      ('hProcess', c_void_p),
      ('hThread', c_void_p),
      ('dwProcessId', c_ulong),
      ('dwThreadId', c_ulong)
    ]

def fetch_local_function_syms(Symbols, prefix):
  syms = Symbols.get_all_functions()

  def is_sym_in_src_dir(sym):
    name, data = sym
    symdata = Symbols.GetLineByOffset(data.Offset)
    if symdata is not None:
      srcfile, line = symdata
      if prefix in srcfile:
        return True
    return False
   
  syms = [x for x in syms if is_sym_in_src_dir(x)]
  return syms

def break_on_all_but_main(Control, Symbols, main_offset):
  mainfile, _ = Symbols.GetLineByOffset(main_offset)
  prefix = '\\'.join(mainfile.split('\\')[:-1])

  for name, rec in fetch_local_function_syms(Symbols, prefix):
    if name == "main":
      continue
    bp = Control.AddBreakpoint2(offset=rec.Offset, enabled=True)

  # All breakpoints are currently discarded: we just sys.exit for cleanup
  return

def setup_everything(binfile):
  from . import client
  from . import symbols
  Client = client.Client()

  Client.Control.SetEngineOptions(0x20) # DEBUG_ENGOPT_INITIAL_BREAK

  Client.CreateProcessAndAttach2(binfile)

  # Load lines as well as general symbols
  sym_opts = Client.Symbols.GetSymbolOptions()
  sym_opts |= symbols.SymbolOptionFlags.SYMOPT_LOAD_LINES
  Client.Symbols.SetSymbolOptions(sym_opts)

  # Need to enter the debugger engine to let it attach properly.
  res = Client.Control.WaitForEvent(timeout=1000)
  if res == S_FALSE:
    # The debugee apparently didn't do anything at all. Rather than risk
    # hanging, bail out at this point.
    client.TerminateProcesses()
    raise Exception("Debuggee did not start in a timely manner")

  # Enable line stepping.
  Client.Control.Execute("l+t")
  # Enable C++ expression interpretation.
  Client.Control.SetExpressionSyntax(cpp=True)

  # We've requested to break into the process at the earliest opportunity,
  # and WaitForEvent'ing means we should have reached that break state.
  # Now set a breakpoint on the main symbol, and "go" until we reach it.
  module_name = Client.Symbols.get_exefile_module_name()
  offset = Client.Symbols.GetOffsetByName("{}!main".format(module_name))
  breakpoint = Client.Control.AddBreakpoint2(offset=offset, enabled=True)
  Client.Control.SetExecutionStatus(control.DebugStatus.DEBUG_STATUS_GO)

  # Problem: there is no guarantee that the client will ever reach main,
  # something else exciting could happen in that time, the host system may
  # be very loaded, and similar. Wait for some period, say, five seconds, and
  # abort afterwards: this is a trade-off between spurious timeouts and
  # completely hanging in the case of a environmental/programming error.
  res = Client.Control.WaitForEvent(timeout=5000)
  if res == S_FALSE:
    client.TerminateProcesses()
    raise Exception("Debuggee did not reach main function in a timely manner")

  break_on_all_but_main(Client.Control, Client.Symbols, offset)

  # Set the default action on all exceptions to be "quit and detach". If we
  # don't, dbgeng will merrily spin at the exception site forever.
  filts = Client.Control.GetNumberEventFilters()
  for x in range(filts[0], filts[0] + filts[1]):
    Client.Control.SetExceptionFilterSecondCommand(x, "qd")

  return Client

def step_once(client):
  client.Control.Execute("p")
  try:
    client.Control.WaitForEvent()
  except Exception as e:
    if client.Control.GetExecutionStatus() == control.DebugStatus.DEBUG_STATUS_NO_DEBUGGEE:
      return None # Debuggee has gone away, likely due to an exception.
    raise e
  # Could assert here that we're in the "break" state
  client.Control.GetExecutionStatus()
  return probe_state(client)

def main_loop(client):
  res = True
  while res is not None:
    res = step_once(client)

def cleanup(client):
  client.TerminateProcesses()
