#include <CoreFoundation/CoreFoundation.h>

#include "lldb-perf/lib/Measurement.h"
#include "lldb-perf/lib/Metric.h"
#include "lldb-perf/lib/TestCase.h"
#include "lldb-perf/lib/Timer.h"
#include "lldb-perf/lib/Xcode.h"

#include <getopt.h>
#include <string>
#include <unistd.h>

using namespace lldb_perf;

class StepTest : public TestCase {
  typedef void (*no_function)(void);

public:
  StepTest(bool use_single_stepping = false)
      : m_main_source("stepping-testcase.cpp"),
        m_use_single_stepping(use_single_stepping),
        m_time_measurements(nullptr) {}

  virtual ~StepTest() {}

  virtual bool Setup(int &argc, const char **&argv) {
    TestCase::Setup(argc, argv);

    // Toggle the fast stepping command on or off as required.
    const char *single_step_cmd = "settings set target.use-fast-stepping false";
    const char *fast_step_cmd = "settings set target.use-fast-stepping true";
    const char *cmd_to_use;

    if (m_use_single_stepping)
      cmd_to_use = single_step_cmd;
    else
      cmd_to_use = fast_step_cmd;

    SBCommandReturnObject return_object;
    m_debugger.GetCommandInterpreter().HandleCommand(cmd_to_use, return_object);
    if (!return_object.Succeeded()) {
      if (return_object.GetError() != NULL)
        printf("Got an error running settings set: %s.\n",
               return_object.GetError());
      else
        printf("Failed running settings set, no error.\n");
    }

    m_target = m_debugger.CreateTarget(m_app_path.c_str());
    m_first_bp = m_target.BreakpointCreateBySourceRegex(
        "Here is some code to stop at originally.", m_main_source);

    const char *file_arg = m_app_path.c_str();
    const char *empty = nullptr;
    const char *args[] = {file_arg, empty};
    SBLaunchInfo launch_info(args);

    return Launch(launch_info);
  }

  void WriteResults(Results &results) {
    // Gotta turn off the last timer now.
    m_individual_step_times.push_back(m_time_measurements.Stop());

    size_t num_time_measurements = m_individual_step_times.size();

    Results::Dictionary &results_dict = results.GetDictionary();
    const char *short_format_string = "step-time-%0.2d";
    const size_t short_size = strlen(short_format_string) + 5;
    char short_buffer[short_size];
    const char *long_format_string =
        "The time it takes for step %d in the step sequence.";
    const size_t long_size = strlen(long_format_string) + 5;
    char long_buffer[long_size];

    for (size_t i = 0; i < num_time_measurements; i++) {
      snprintf(short_buffer, short_size, short_format_string, i);
      snprintf(long_buffer, long_size, long_format_string, i);

      results_dict.AddDouble(short_buffer, long_buffer,
                             m_individual_step_times[i]);
    }
    results_dict.AddDouble("total-time", "Total time spent stepping.",
                           m_time_measurements.GetMetric().GetSum());
    results_dict.AddDouble(
        "stddev-time", "StdDev of time spent stepping.",
        m_time_measurements.GetMetric().GetStandardDeviation());

    results.Write(m_out_path.c_str());
  }

  const char *GetExecutablePath() const {
    if (m_app_path.empty())
      return NULL;
    return m_app_path.c_str();
  }

  const char *GetResultFilePath() const {
    if (m_out_path.empty())
      return NULL;
    return m_out_path.c_str();
  }

  void SetExecutablePath(const char *path) {
    if (path && path[0])
      m_app_path = path;
    else
      m_app_path.clear();
  }

  void SetResultFilePath(const char *path) {
    if (path && path[0])
      m_out_path = path;
    else
      m_out_path.clear();
  }

  void SetUseSingleStep(bool use_it) { m_use_single_stepping = use_it; }

private:
  virtual void TestStep(int counter, ActionWanted &next_action) {
    if (counter > 0) {
      m_individual_step_times.push_back(m_time_measurements.Stop());
    }

    // Disable the breakpoint, just in case it gets multiple locations we don't
    // want that confusing the stepping.
    if (counter == 0)
      m_first_bp.SetEnabled(false);

    next_action.StepOver(m_process.GetThreadAtIndex(0));
    m_time_measurements.Start();
  }

  SBBreakpoint m_first_bp;
  SBFileSpec m_main_source;
  TimeMeasurement<no_function> m_time_measurements;
  std::vector<double> m_individual_step_times;
  bool m_use_single_stepping;
  std::string m_app_path;
  std::string m_out_path;
};

struct Options {
  std::string test_file_path;
  std::string out_file;
  bool verbose;
  bool fast_step;
  bool error;
  bool print_help;

  Options()
      : verbose(false), fast_step(true), error(false), print_help(false) {}
};

static struct option g_long_options[] = {
    {"verbose", no_argument, NULL, 'v'},
    {"single-step", no_argument, NULL, 's'},
    {"test-file", required_argument, NULL, 't'},
    {"out-file", required_argument, NULL, 'o'},
    {NULL, 0, NULL, 0}};

std::string GetShortOptionString(struct option *long_options) {
  std::string option_string;
  for (int i = 0; long_options[i].name != NULL; ++i) {
    if (long_options[i].flag == NULL) {
      option_string.push_back((char)long_options[i].val);
      switch (long_options[i].has_arg) {
      default:
      case no_argument:
        break;
      case required_argument:
        option_string.push_back(':');
        break;
      case optional_argument:
        option_string.append(2, ':');
        break;
      }
    }
  }
  return option_string;
}

int main(int argc, const char *argv[]) {

  // Prepare for & make calls to getopt_long_only.

  std::string short_option_string(GetShortOptionString(g_long_options));

  StepTest test;

  Options option_data;
  bool done = false;

#if __GLIBC__
  optind = 0;
#else
  optreset = 1;
  optind = 1;
#endif
  while (!done) {
    int long_options_index = -1;
    const int short_option = ::getopt_long_only(
        argc, const_cast<char **>(argv), short_option_string.c_str(),
        g_long_options, &long_options_index);

    switch (short_option) {
    case 0:
      // Already handled
      break;

    case -1:
      done = true;
      break;

    case '?':
      option_data.print_help = true;
      break;

    case 'h':
      option_data.print_help = true;
      break;

    case 'v':
      option_data.verbose = true;
      break;

    case 's':
      option_data.fast_step = false;
      test.SetUseSingleStep(true);
      break;

    case 't': {
      SBFileSpec file(optarg);
      if (file.Exists())
        test.SetExecutablePath(optarg);
      else
        fprintf(stderr, "error: file specified in --test-file (-t) option "
                        "doesn't exist: '%s'\n",
                optarg);
    } break;

    case 'o':
      test.SetResultFilePath(optarg);
      break;

    default:
      option_data.error = true;
      option_data.print_help = true;
      fprintf(stderr, "error: unrecognized option %c\n", short_option);
      break;
    }
  }

  if (option_data.print_help) {
    puts(R"(
NAME
    lldb-perf-stepping -- a tool that measures LLDB peformance of simple stepping operations.

SYNOPSIS
    lldb-perf-stepping --test-file=FILE [--out-file=PATH --verbose --fast-step]
             
DESCRIPTION
    Runs a set of stepping operations, timing each step and outputs results
    to a plist file.
)");
    exit(0);
  }
  if (option_data.error) {
    exit(1);
  }

  if (test.GetExecutablePath() == NULL) {
    // --clang is mandatory
    option_data.print_help = true;
    option_data.error = true;
    fprintf(stderr, "error: the '--test-file=PATH' option is mandatory\n");
  }

  // Update argc and argv after parsing options
  argc -= optind;
  argv += optind;

  test.SetVerbose(true);
  TestCase::Run(test, argc, argv);
  return 0;
}
