// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2013, Google, Inc. All rights reserved
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

/*
 * Functions for unit tests.  See lib/unittest/include/unittest.h for usage.
 */
#include <assert.h>
#include <debug.h>
#include <inttypes.h>
#include <lib/console.h>
#include <lib/fit/defer.h>
#include <lib/unittest/unittest.h>
#include <platform.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zircon/compiler.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#include <kernel/mutex.h>
#include <kernel/thread.h>
#include <vm/vm_aspace.h>

namespace {

// Ensures unittests are not run concurrently.
DECLARE_SINGLETON_MUTEX(UnittestLock);
unsigned long g_repeat;

// External references to the testcase registration tables.
extern "C" unittest_testcase_registration_t __start_unittest_testcases[];
extern "C" unittest_testcase_registration_t __stop_unittest_testcases[];

void usage(const char* progname) {
  printf(
      "Usage:\n"
      "%s <case>\n"
      "  where case is a specific testcase name, or...\n"
      "  all : run all tests\n"
      "  ?   : list tests\n"
      "  [-r num]  : repeat a test case num times\n",
      progname);
}

void list_cases(void) {
  size_t count = 0;
  size_t max_namelen = 0;

  const unittest_testcase_registration_t* testcase;
  for (testcase = __start_unittest_testcases; testcase != __stop_unittest_testcases; ++testcase) {
    if (testcase->name) {
      size_t namelen = strlen(testcase->name);
      if (max_namelen < namelen)
        max_namelen = namelen;
      count++;
    }
  }

  printf("There %s %zu test case%s available...\n", count == 1 ? "is" : "are", count,
         count == 1 ? "" : "s");

  for (testcase = __start_unittest_testcases; testcase != __stop_unittest_testcases; ++testcase) {
    if (testcase->name)
      printf("  %-*s : %s\n", static_cast<int>(max_namelen), testcase->name,
             testcase->desc ? testcase->desc : "<no description>");
  }
}

bool run_unittest(const unittest_testcase_registration_t* testcase) {
  size_t max_namelen = 0;
  size_t passed = 0;

  DEBUG_ASSERT(testcase);
  DEBUG_ASSERT(testcase->name);
  DEBUG_ASSERT(!!testcase->tests == !!testcase->test_cnt);

  for (size_t i = 0; i < testcase->test_cnt; ++i) {
    const unittest_registration_t* test = &testcase->tests[i];
    if (test->name) {
      size_t namelen = strlen(test->name);
      if (max_namelen < namelen)
        max_namelen = namelen;
    }
  }

  unittest_printf("%s : Running %zu test%s...\n", testcase->name, testcase->test_cnt,
                  testcase->test_cnt == 1 ? "" : "s");

  zx_time_t testcase_start = current_time();

  for (unsigned long j = 0; j < g_repeat; j++) {
    bool good = true;
    for (size_t i = 0; i < testcase->test_cnt; ++i) {
      const unittest_registration_t* test = &testcase->tests[i];

      unittest_printf("  %-*s : ", static_cast<int>(max_namelen), test->name ? test->name : "");

      zx_time_t test_start = current_time();
      good &= test->fn ? test->fn() : false;
      zx_duration_t test_runtime = current_time() - test_start;

      unittest_printf("%s (%" PRIi64 " nSec) ", good ? "PASSED" : "FAILED", test_runtime);
      if (g_repeat > 1) {
        unittest_printf(" [%lu / %lu]", j + 1, g_repeat);
      }
      unittest_printf("\n");
      if (good) {
        if (j == g_repeat - 1) {
          passed++;
        }
      } else {
        printf("  %-*s : ", static_cast<int>(max_namelen), test->name ? test->name : "");
        break;
      }
    }
  }

  zx_duration_t testcase_runtime = current_time() - testcase_start;

  unittest_printf("%s : %sll tests passed (%zu/%zu) in %" PRIi64 " nSec\n", testcase->name,
                  passed != testcase->test_cnt ? "Not a" : "A", passed, testcase->test_cnt,
                  testcase_runtime);

  return passed == testcase->test_cnt;
}

// Runs the testcase specified by |arg| and returns 1 if test passes.
//
// |arg| is a const unittest_testcase_registration_t*.
int run_unittest_thread_entry(void* arg) {
  auto* testcase = static_cast<const unittest_testcase_registration_t*>(arg);
  return run_unittest(testcase);
}

// Runs |testcase| in another thread and waits for it to complete.
//
// Returns true if the test passed.
bool run_testcase_in_thread(const unittest_testcase_registration_t* testcase) {
  fbl::RefPtr<VmAspace> aspace = VmAspace::Create(VmAspace::TYPE_USER, "unittest");
  if (!aspace) {
    unittest_printf("failed to create unittest user aspace\n");
    return false;
  }
  auto destroy_aspace = fit::defer([&]() {
    zx_status_t status = aspace->Destroy();
    DEBUG_ASSERT(status == ZX_OK);
  });
  Thread* t =
      Thread::Create("unittest", run_unittest_thread_entry,
                     const_cast<void*>(static_cast<const void*>(testcase)), DEFAULT_PRIORITY);
  if (!t) {
    unittest_printf("failed to create unittest thread\n");
    return false;
  }
  aspace->AttachToThread(t);

  t->Resume();
  int success = 0;
  zx_status_t status = t->Join(&success, ZX_TIME_INFINITE);
  if (status != ZX_OK) {
    unittest_printf("failed to join unittest thread: %d\n", status);
    return false;
  }
  return success;
}

int run_unittests_locked(int argc, const cmd_args* argv, uint32_t flags)
    TA_REQ(UnittestLock::Get()) {
  DEBUG_ASSERT(UnittestLock::Get()->lock().IsHeld());
  if (argc < 2) {
    usage(argv[0].str);
    return 0;
  }

  const char* casename = argv[1].str;

  if (!strcmp(casename, "?")) {
    list_cases();
    return 0;
  }
  g_repeat = 1;
  if (!strcmp(casename, "-r")) {
    if (argc < 4) {
      usage(argv[0].str);
      return 0;
    }
    g_repeat = argv[2].u;
    casename = argv[3].str;
  }

  bool run_all = !strcmp(casename, "all");
  const unittest_testcase_registration_t* testcase;
  size_t chosen = 0;
  size_t passed = 0;

  const size_t num_tests = run_all ? __stop_unittest_testcases - __start_unittest_testcases : 1;
  // Array of names with a NULL sentinel at the end.
  const char** failed_names = static_cast<const char**>(calloc(num_tests + 1, sizeof(char*)));
  const char** fn = failed_names;

  for (testcase = __start_unittest_testcases; testcase != __stop_unittest_testcases; ++testcase) {
    if (testcase->name) {
      if (run_all || !strcmp(casename, testcase->name)) {
        chosen++;

        bool status = run_testcase_in_thread(testcase);
        if (!status) {
          break;
        }
        printf("\n");
        if (status) {
          passed++;
        } else {
          *fn++ = testcase->name;
        }

        if (!run_all)
          break;
      }
    }
  }

  int ret = 0;
  if (!run_all && !chosen) {
    ret = -1;
    unittest_printf("Test case \"%s\" not found!\n", casename);
    list_cases();
  } else {
    unittest_printf("SUMMARY: Ran %zu test case%s: %zu failed\n", chosen, chosen == 1 ? "" : "s",
                    chosen - passed);
    if (passed < chosen) {
      ret = -1;
      unittest_printf("\nThe following test cases failed:\n");
      for (fn = failed_names; *fn != NULL; fn++) {
        unittest_printf("%s\n", *fn);
      }
    }
  }

  free(failed_names);
  return ret;
}

int run_unittests(int argc, const cmd_args* argv, uint32_t flags) {
  Guard<Mutex> guard{UnittestLock::Get()};
  return run_unittests_locked(argc, argv, flags);
}

}  // namespace

STATIC_COMMAND_START
STATIC_COMMAND("ut", "Run unittests", run_unittests)
STATIC_COMMAND_END(unittests)
