/*
 * Copyright © 2020 Valve Corporation
 *
 * SPDX-License-Identifier: MIT
 */
#include "aco_ir.h"

#include <llvm-c/Target.h>

#include "framework.h"
#include <getopt.h>
#include <map>
#include <set>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <unistd.h>
#include <vector>

static const char* help_message =
   "Usage: %s [-h] [-l --list] [--no-check] [TEST [TEST ...]]\n"
   "\n"
   "Run ACO unit test(s). If TEST is not provided, all tests are run.\n"
   "\n"
   "positional arguments:\n"
   "  TEST        Run TEST. If TEST ends with a '.', run tests with names\n"
   "              starting with TEST. The test variant (after the '/') can\n"
   "              be omitted to run all variants\n"
   "\n"
   "optional arguments:\n"
   "  -h, --help  Show this help message and exit.\n"
   "  -l --list   List unit tests.\n"
   "  --no-check  Print test output instead of checking it.\n";

std::map<std::string, TestDef> *tests = NULL;
FILE* output = NULL;

static TestDef current_test;
static unsigned tests_written = 0;
static FILE* checker_stdin = NULL;
static char* checker_stdin_data = NULL;
static size_t checker_stdin_size = 0;

static char* output_data = NULL;
static size_t output_size = 0;
static size_t output_offset = 0;

static char current_variant[64] = {0};
static std::set<std::string>* variant_filter = NULL;

bool test_failed = false;
bool test_skipped = false;
static char fail_message[256] = {0};

void
write_test()
{
   if (!checker_stdin) {
      /* not entirely correct, but shouldn't matter */
      tests_written++;
      return;
   }

   fflush(output);
   if (output_offset == output_size && !test_skipped && !test_failed)
      return;

   char* data = output_data + output_offset;
   uint32_t size = output_size - output_offset;

   fwrite("test", 1, 4, checker_stdin);
   fwrite(current_test.name, 1, strlen(current_test.name) + 1, checker_stdin);
   fwrite(current_variant, 1, strlen(current_variant) + 1, checker_stdin);
   fwrite(current_test.source_file, 1, strlen(current_test.source_file) + 1, checker_stdin);
   if (test_failed || test_skipped) {
      const char* res = test_failed ? "failed" : "skipped";
      fwrite("\x01", 1, 1, checker_stdin);
      fwrite(res, 1, strlen(res) + 1, checker_stdin);
      fwrite(fail_message, 1, strlen(fail_message) + 1, checker_stdin);
   } else {
      fwrite("\x00", 1, 1, checker_stdin);
   }
   fwrite(&size, 4, 1, checker_stdin);
   fwrite(data, 1, size, checker_stdin);

   tests_written++;
   output_offset += size;
}

bool
set_variant(const char* name)
{
   if (variant_filter && !variant_filter->count(name))
      return false;

   write_test();
   test_failed = false;
   test_skipped = false;
   strncpy(current_variant, name, sizeof(current_variant) - 1);

   printf("Running '%s/%s'\n", current_test.name, name);

   return true;
}

void
fail_test(const char* fmt, ...)
{
   va_list args;
   va_start(args, fmt);

   test_failed = true;
   vsnprintf(fail_message, sizeof(fail_message), fmt, args);

   va_end(args);
}

void
skip_test(const char* fmt, ...)
{
   va_list args;
   va_start(args, fmt);

   test_skipped = true;
   vsnprintf(fail_message, sizeof(fail_message), fmt, args);

   va_end(args);
}

void
run_test(TestDef def)
{
   current_test = def;
   output_data = NULL;
   output_size = 0;
   output_offset = 0;
   test_failed = false;
   test_skipped = false;
   memset(current_variant, 0, sizeof(current_variant));

   if (checker_stdin)
      output = open_memstream(&output_data, &output_size);
   else
      output = stdout;

   current_test.func();
   write_test();

   if (checker_stdin)
      fclose(output);
   free(output_data);
}

int
check_output(char** argv)
{
   fflush(stdout);
   fflush(stderr);

   fclose(checker_stdin);

   int stdin_pipe[2];
   pipe(stdin_pipe);

   pid_t child_pid = fork();
   if (child_pid == -1) {
      fprintf(stderr, "%s: fork() failed: %s\n", argv[0], strerror(errno));
      return 99;
   } else if (child_pid != 0) {
      /* Evaluate test output externally using Python */
      dup2(stdin_pipe[0], STDIN_FILENO);
      close(stdin_pipe[0]);
      close(stdin_pipe[1]);

      execlp(ACO_TEST_PYTHON_BIN, ACO_TEST_PYTHON_BIN, ACO_TEST_SOURCE_DIR "/check_output.py",
             NULL);
      fprintf(stderr, "%s: execlp() failed: %s\n", argv[0], strerror(errno));
      return 99;
   } else {
      /* Feed input data to the Python process. Writing large streams to
       * stdin will block eventually, so this is done in a forked process
       * to let the test checker process chunks of data as they arrive */
      write(stdin_pipe[1], checker_stdin_data, checker_stdin_size);
      close(stdin_pipe[0]);
      close(stdin_pipe[1]);
      _exit(0);
   }
}

bool
match_test(std::string name, std::string pattern)
{
   if (name.length() < pattern.length())
      return false;
   if (pattern.back() == '.')
      name.resize(pattern.length());
   return name == pattern;
}

int
main(int argc, char** argv)
{
   int print_help = 0;
   int do_list = 0;
   int do_check = 1;
   const struct option opts[] = {{"help", no_argument, &print_help, 1},
                                 {"list", no_argument, &do_list, 1},
                                 {"no-check", no_argument, &do_check, 0},
                                 {NULL, 0, NULL, 0}};

   int c;
   while ((c = getopt_long(argc, argv, "hl", opts, NULL)) != -1) {
      switch (c) {
      case 'h': print_help = 1; break;
      case 'l': do_list = 1; break;
      case 0: break;
      case '?':
      default: fprintf(stderr, "%s: Invalid argument\n", argv[0]); return 99;
      }
   }

   if (print_help) {
      fprintf(stderr, help_message, argv[0]);
      return 99;
   }

   if (!tests)
      tests = new std::map<std::string, TestDef>;

   if (do_list) {
      for (auto test : *tests)
         printf("%s\n", test.first.c_str());
      return 99;
   }

   std::vector<std::pair<std::string, std::string>> names;
   for (int i = optind; i < argc; i++) {
      std::string name = argv[i];
      std::string variant;
      size_t pos = name.find('/');
      if (pos != std::string::npos) {
         variant = name.substr(pos + 1);
         name = name.substr(0, pos);
      }
      names.emplace_back(std::pair<std::string, std::string>(name, variant));
   }

   if (do_check)
      checker_stdin = open_memstream(&checker_stdin_data, &checker_stdin_size);

   LLVMInitializeAMDGPUTargetInfo();
   LLVMInitializeAMDGPUTarget();
   LLVMInitializeAMDGPUTargetMC();
   LLVMInitializeAMDGPUDisassembler();

   aco::init();

   for (auto pair : *tests) {
      bool found = names.empty();
      bool all_variants = names.empty();
      std::set<std::string> variants;
      for (const std::pair<std::string, std::string>& name : names) {
         if (match_test(pair.first, name.first)) {
            found = true;
            if (name.second.empty())
               all_variants = true;
            else
               variants.insert(name.second);
         }
      }

      if (found) {
         variant_filter = all_variants ? NULL : &variants;
         printf("Running '%s'\n", pair.first.c_str());
         run_test(pair.second);
      }
   }
   if (!tests_written) {
      fprintf(stderr, "%s: No matching tests\n", argv[0]);
      return 99;
   }

   if (checker_stdin) {
      printf("\n");
      return check_output(argv);
   } else {
      printf("Tests ran\n");
      return 99;
   }
}
