/* Python interface to record targets.

   Copyright 2016-2020 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "py-instruction.h"
#include "py-record.h"
#include "py-record-btrace.h"
#include "py-record-full.h"
#include "target.h"
#include "gdbthread.h"

/* Python Record type.  */

static PyTypeObject recpy_record_type = {
  PyVarObject_HEAD_INIT (NULL, 0)
};

/* Python RecordInstruction type.  */

PyTypeObject recpy_insn_type = {
  PyVarObject_HEAD_INIT (NULL, 0)
};

/* Python RecordFunctionSegment type.  */

PyTypeObject recpy_func_type = {
  PyVarObject_HEAD_INIT (NULL, 0)
};

/* Python RecordGap type.  */

PyTypeObject recpy_gap_type = {
  PyVarObject_HEAD_INIT (NULL, 0)
};

/* Python RecordGap object.  */
typedef struct
{
  PyObject_HEAD

  /* Reason code.  */
  int reason_code;

  /* Reason message.  */
  const char *reason_string;

  /* Element number.  */
  Py_ssize_t number;
} recpy_gap_object;

/* Implementation of record.method.  */

static PyObject *
recpy_method (PyObject *self, void* closure)
{
  const recpy_record_object * const obj = (recpy_record_object *) self;

  if (obj->method == RECORD_METHOD_FULL)
    return recpy_full_method (self, closure);

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_method (self, closure);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Implementation of record.format.  */

static PyObject *
recpy_format (PyObject *self, void* closure)
{
  const recpy_record_object * const obj = (recpy_record_object *) self;

  if (obj->method == RECORD_METHOD_FULL)
    return recpy_full_format (self, closure);

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_format (self, closure);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Implementation of record.goto (instruction) -> None.  */

static PyObject *
recpy_goto (PyObject *self, PyObject *value)
{
  const recpy_record_object * const obj = (recpy_record_object *) self;

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_goto (self, value);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Implementation of record.replay_position [instruction]  */

static PyObject *
recpy_replay_position (PyObject *self, void *closure)
{
  const recpy_record_object * const obj = (recpy_record_object *) self;

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_replay_position (self, closure);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Implementation of record.instruction_history [list].  */

static PyObject *
recpy_instruction_history (PyObject *self, void* closure)
{
  const recpy_record_object * const obj = (recpy_record_object *) self;

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_instruction_history (self, closure);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Implementation of record.function_call_history [list].  */

static PyObject *
recpy_function_call_history (PyObject *self, void* closure)
{
  const recpy_record_object * const obj = (recpy_record_object *) self;

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_function_call_history (self, closure);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Implementation of record.begin [instruction].  */

static PyObject *
recpy_begin (PyObject *self, void* closure)
{
  const recpy_record_object * const obj = (recpy_record_object *) self;

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_begin (self, closure);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Implementation of record.end [instruction].  */

static PyObject *
recpy_end (PyObject *self, void* closure)
{
  const recpy_record_object * const obj = (recpy_record_object *) self;

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_end (self, closure);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Create a new gdb.RecordInstruction object.  */

PyObject *
recpy_insn_new (thread_info *thread, enum record_method method, Py_ssize_t number)
{
  recpy_element_object * const obj = PyObject_New (recpy_element_object,
						   &recpy_insn_type);

  if (obj == NULL)
   return NULL;

  obj->thread = thread;
  obj->method = method;
  obj->number = number;

  return (PyObject *) obj;
}

/* Implementation of RecordInstruction.sal [gdb.Symtab_and_line].  */

static PyObject *
recpy_insn_sal (PyObject *self, void *closure)
{
  const recpy_element_object * const obj = (recpy_element_object *) self;

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_insn_sal (self, closure);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Implementation of RecordInstruction.pc [int].  */

static PyObject *
recpy_insn_pc (PyObject *self, void *closure)
{
  const recpy_element_object * const obj = (recpy_element_object *) self;

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_insn_pc (self, closure);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Implementation of RecordInstruction.data [buffer].  */

static PyObject *
recpy_insn_data (PyObject *self, void *closure)
{
  const recpy_element_object * const obj = (recpy_element_object *) self;

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_insn_data (self, closure);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Implementation of RecordInstruction.decoded [str].  */

static PyObject *
recpy_insn_decoded (PyObject *self, void *closure)
{
  const recpy_element_object * const obj = (recpy_element_object *) self;

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_insn_decoded (self, closure);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Implementation of RecordInstruction.size [int].  */

static PyObject *
recpy_insn_size (PyObject *self, void *closure)
{
  const recpy_element_object * const obj = (recpy_element_object *) self;

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_insn_size (self, closure);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Implementation of RecordInstruction.is_speculative [bool].  */

static PyObject *
recpy_insn_is_speculative (PyObject *self, void *closure)
{
  const recpy_element_object * const obj = (recpy_element_object *) self;

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_insn_is_speculative (self, closure);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Create a new gdb.RecordFunctionSegment object.  */

PyObject *
recpy_func_new (thread_info *thread, enum record_method method, Py_ssize_t number)
{
  recpy_element_object * const obj = PyObject_New (recpy_element_object,
						   &recpy_func_type);

  if (obj == NULL)
   return NULL;

  obj->thread = thread;
  obj->method = method;
  obj->number = number;

  return (PyObject *) obj;
}

/* Implementation of RecordFunctionSegment.level [int].  */

static PyObject *
recpy_func_level (PyObject *self, void *closure)
{
  const recpy_element_object * const obj = (recpy_element_object *) self;

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_func_level (self, closure);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Implementation of RecordFunctionSegment.symbol [gdb.Symbol].  */

static PyObject *
recpy_func_symbol (PyObject *self, void *closure)
{
  const recpy_element_object * const obj = (recpy_element_object *) self;

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_func_symbol (self, closure);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Implementation of RecordFunctionSegment.instructions [list].  */

static PyObject *
recpy_func_instructions (PyObject *self, void *closure)
{
  const recpy_element_object * const obj = (recpy_element_object *) self;

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_func_instructions (self, closure);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Implementation of RecordFunctionSegment.up [RecordFunctionSegment].  */

static PyObject *
recpy_func_up (PyObject *self, void *closure)
{
  const recpy_element_object * const obj = (recpy_element_object *) self;

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_func_up (self, closure);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Implementation of RecordFunctionSegment.prev [RecordFunctionSegment].  */

static PyObject *
recpy_func_prev (PyObject *self, void *closure)
{
  const recpy_element_object * const obj = (recpy_element_object *) self;

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_func_prev (self, closure);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Implementation of RecordFunctionSegment.next [RecordFunctionSegment].  */

static PyObject *
recpy_func_next (PyObject *self, void *closure)
{
  const recpy_element_object * const obj = (recpy_element_object *) self;

  if (obj->method == RECORD_METHOD_BTRACE)
    return recpy_bt_func_next (self, closure);

  return PyErr_Format (PyExc_NotImplementedError, _("Not implemented."));
}

/* Implementation of RecordInstruction.number [int] and
   RecordFunctionSegment.number [int].  */

static PyObject *
recpy_element_number (PyObject *self, void* closure)
{
  const recpy_element_object * const obj = (recpy_element_object *) self;

  return PyInt_FromSsize_t (obj->number);
}

/* Implementation of RecordInstruction.__hash__ [int] and
   RecordFunctionSegment.__hash__ [int].  */

static Py_hash_t
recpy_element_hash (PyObject *self)
{
  const recpy_element_object * const obj = (recpy_element_object *) self;

  return obj->number;
}

/* Implementation of operator == and != of RecordInstruction and
   RecordFunctionSegment.  */

static PyObject *
recpy_element_richcompare (PyObject *self, PyObject *other, int op)
{
  const recpy_element_object * const obj1 = (recpy_element_object *) self;
  const recpy_element_object * const obj2 = (recpy_element_object *) other;

  if (Py_TYPE (self) != Py_TYPE (other))
    {
      Py_INCREF (Py_NotImplemented);
      return Py_NotImplemented;
    }

  switch (op)
  {
    case Py_EQ:
      if (obj1->thread == obj2->thread
	  && obj1->method == obj2->method
	  && obj1->number == obj2->number)
	Py_RETURN_TRUE;
      else
	Py_RETURN_FALSE;

    case Py_NE:
      if (obj1->thread != obj2->thread
	  || obj1->method != obj2->method
	  || obj1->number != obj2->number)
	Py_RETURN_TRUE;
      else
	Py_RETURN_FALSE;

    default:
      break;
  }

  Py_INCREF (Py_NotImplemented);
  return Py_NotImplemented;
}

/* Create a new gdb.RecordGap object.  */

PyObject *
recpy_gap_new (int reason_code, const char *reason_string, Py_ssize_t number)
{
  recpy_gap_object * const obj = PyObject_New (recpy_gap_object,
					       &recpy_gap_type);

  if (obj == NULL)
   return NULL;

  obj->reason_code = reason_code;
  obj->reason_string = reason_string;
  obj->number = number;

  return (PyObject *) obj;
}

/* Implementation of RecordGap.number [int].  */

static PyObject *
recpy_gap_number (PyObject *self, void *closure)
{
  const recpy_gap_object * const obj = (const recpy_gap_object *) self;

  return PyInt_FromSsize_t (obj->number);
}

/* Implementation of RecordGap.error_code [int].  */

static PyObject *
recpy_gap_reason_code (PyObject *self, void *closure)
{
  const recpy_gap_object * const obj = (const recpy_gap_object *) self;

  return PyInt_FromLong (obj->reason_code);
}

/* Implementation of RecordGap.error_string [str].  */

static PyObject *
recpy_gap_reason_string (PyObject *self, void *closure)
{
  const recpy_gap_object * const obj = (const recpy_gap_object *) self;

  return PyString_FromString (obj->reason_string);
}

/* Record method list.  */

static PyMethodDef recpy_record_methods[] = {
  { "goto", recpy_goto, METH_VARARGS,
    "goto (instruction|function_call) -> None.\n\
Rewind to given location."},
  { NULL }
};

/* Record member list.  */

static gdb_PyGetSetDef recpy_record_getset[] = {
  { "method", recpy_method, NULL, "Current recording method.", NULL },
  { "format", recpy_format, NULL, "Current recording format.", NULL },
  { "replay_position", recpy_replay_position, NULL, "Current replay position.",
    NULL },
  { "instruction_history", recpy_instruction_history, NULL,
    "List of instructions in current recording.", NULL },
  { "function_call_history", recpy_function_call_history, NULL,
    "List of function calls in current recording.", NULL },
  { "begin", recpy_begin, NULL,
    "First instruction in current recording.", NULL },
  { "end", recpy_end, NULL,
    "One past the last instruction in current recording.  This is typically \
the current instruction and is used for e.g. record.goto (record.end).", NULL },
  { NULL }
};

/* RecordInstruction member list.  */

static gdb_PyGetSetDef recpy_insn_getset[] = {
  { "number", recpy_element_number, NULL, "instruction number", NULL},
  { "sal", recpy_insn_sal, NULL, "associated symbol and line", NULL},
  { "pc", recpy_insn_pc, NULL, "instruction address", NULL},
  { "data", recpy_insn_data, NULL, "raw instruction data", NULL},
  { "decoded", recpy_insn_decoded, NULL, "decoded instruction", NULL},
  { "size", recpy_insn_size, NULL, "instruction size in byte", NULL},
  { "is_speculative", recpy_insn_is_speculative, NULL, "if the instruction was \
  executed speculatively", NULL},
  { NULL }
};

/* RecordFunctionSegment member list.  */

static gdb_PyGetSetDef recpy_func_getset[] = {
  { "number", recpy_element_number, NULL, "function segment number", NULL},
  { "level", recpy_func_level, NULL, "call stack level", NULL},
  { "symbol", recpy_func_symbol, NULL, "associated line and symbol", NULL},
  { "instructions", recpy_func_instructions, NULL, "list of instructions in \
this function segment", NULL},
  { "up", recpy_func_up, NULL, "caller or returned-to function segment", NULL},
  { "prev", recpy_func_prev, NULL, "previous segment of this function", NULL},
  { "next", recpy_func_next, NULL, "next segment of this function", NULL},
  { NULL }
};

/* RecordGap member list.  */

static gdb_PyGetSetDef recpy_gap_getset[] = {
  { "number", recpy_gap_number, NULL, "element number", NULL},
  { "reason_code", recpy_gap_reason_code, NULL, "reason code", NULL},
  { "reason_string", recpy_gap_reason_string, NULL, "reason string", NULL},
  { NULL }
};

/* Sets up the record API in the gdb module.  */

int
gdbpy_initialize_record (void)
{
  recpy_record_type.tp_new = PyType_GenericNew;
  recpy_record_type.tp_flags = Py_TPFLAGS_DEFAULT;
  recpy_record_type.tp_basicsize = sizeof (recpy_record_object);
  recpy_record_type.tp_name = "gdb.Record";
  recpy_record_type.tp_doc = "GDB record object";
  recpy_record_type.tp_methods = recpy_record_methods;
  recpy_record_type.tp_getset = recpy_record_getset;

  recpy_insn_type.tp_new = PyType_GenericNew;
  recpy_insn_type.tp_flags = Py_TPFLAGS_DEFAULT;
  recpy_insn_type.tp_basicsize = sizeof (recpy_element_object);
  recpy_insn_type.tp_name = "gdb.RecordInstruction";
  recpy_insn_type.tp_doc = "GDB recorded instruction object";
  recpy_insn_type.tp_getset = recpy_insn_getset;
  recpy_insn_type.tp_richcompare = recpy_element_richcompare;
  recpy_insn_type.tp_hash = recpy_element_hash;
  recpy_insn_type.tp_base = &py_insn_type;

  recpy_func_type.tp_new = PyType_GenericNew;
  recpy_func_type.tp_flags = Py_TPFLAGS_DEFAULT;
  recpy_func_type.tp_basicsize = sizeof (recpy_element_object);
  recpy_func_type.tp_name = "gdb.RecordFunctionSegment";
  recpy_func_type.tp_doc = "GDB record function segment object";
  recpy_func_type.tp_getset = recpy_func_getset;
  recpy_func_type.tp_richcompare = recpy_element_richcompare;
  recpy_func_type.tp_hash = recpy_element_hash;

  recpy_gap_type.tp_new = PyType_GenericNew;
  recpy_gap_type.tp_flags = Py_TPFLAGS_DEFAULT;
  recpy_gap_type.tp_basicsize = sizeof (recpy_gap_object);
  recpy_gap_type.tp_name = "gdb.RecordGap";
  recpy_gap_type.tp_doc = "GDB recorded gap object";
  recpy_gap_type.tp_getset = recpy_gap_getset;

  if (PyType_Ready (&recpy_record_type) < 0
      || PyType_Ready (&recpy_insn_type) < 0
      || PyType_Ready (&recpy_func_type) < 0
      || PyType_Ready (&recpy_gap_type) < 0)
    return -1;
  else
    return 0;
}

/* Implementation of gdb.start_recording (method) -> gdb.Record.  */

PyObject *
gdbpy_start_recording (PyObject *self, PyObject *args)
{
  const char *method = NULL;
  const char *format = NULL;
  PyObject *ret = NULL;

  if (!PyArg_ParseTuple (args, "|ss", &method, &format))
    return NULL;

  try
    {
      record_start (method, format, 0);
      ret = gdbpy_current_recording (self, args);
    }
  catch (const gdb_exception &except)
    {
      gdbpy_convert_exception (except);
    }

  return ret;
}

/* Implementation of gdb.current_recording (self) -> gdb.Record.  */

PyObject *
gdbpy_current_recording (PyObject *self, PyObject *args)
{
  recpy_record_object *ret = NULL;

  if (find_record_target () == NULL)
    Py_RETURN_NONE;

  ret = PyObject_New (recpy_record_object, &recpy_record_type);
  ret->thread = inferior_thread ();
  ret->method = target_record_method (ret->thread->ptid);

  return (PyObject *) ret;
}

/* Implementation of gdb.stop_recording (self) -> None.  */

PyObject *
gdbpy_stop_recording (PyObject *self, PyObject *args)
{
  try
    {
      record_stop (0);
    }
  catch (const gdb_exception &except)
    {
      GDB_PY_HANDLE_EXCEPTION (except);
    }

  Py_RETURN_NONE;
}
