// Copyright 2019 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

#include <algorithm>
#include <cstring>

#include "light_public_overrides/pw_unit_test/framework_backend.h"
#include "pw_assert/check.h"

namespace pw {
namespace unit_test {

void RegisterEventHandler(EventHandler* event_handler) {
  internal::Framework::Get().RegisterEventHandler(event_handler);
}

namespace internal {

// Singleton instance of the unit test framework class.
Framework Framework::framework_;

// Linked list of all test cases in the test executable. This is static as it is
// populated using static initialization.
TestInfo* Framework::tests_ = nullptr;

void Framework::RegisterTest(TestInfo* new_test) const {
  // If the test list is empty, set new_test as the first test.
  if (tests_ == nullptr) {
    tests_ = new_test;
    return;
  }

  // Append the test case to the end of the test list.
  TestInfo* info = tests_;
  for (; info->next() != nullptr; info = info->next()) {
  }
  info->set_next(new_test);
}

int Framework::RunAllTests() {
  exit_status_ = 0;
  run_tests_summary_.passed_tests = 0;
  run_tests_summary_.failed_tests = 0;
  run_tests_summary_.skipped_tests = 0;
  run_tests_summary_.disabled_tests = 0;

  if (event_handler_ != nullptr) {
    event_handler_->RunAllTestsStart();
  }
  for (const TestInfo* test = tests_; test != nullptr; test = test->next()) {
    if (ShouldRunTest(*test)) {
      test->run();
    } else if (!test->enabled()) {
      run_tests_summary_.disabled_tests++;

      if (event_handler_ != nullptr) {
        event_handler_->TestCaseDisabled(test->test_case());
      }
    } else {
      run_tests_summary_.skipped_tests++;
    }
  }
  if (event_handler_ != nullptr) {
    event_handler_->RunAllTestsEnd(run_tests_summary_);
  }
  return exit_status_;
}

void Framework::SetUpTestSuiteIfNeeded(SetUpTestSuiteFunc set_up_ts) const {
  if (set_up_ts == Test::SetUpTestSuite) {
    return;
  }

  for (TestInfo* info = tests_; info != current_test_; info = info->next()) {
    if (info->test_case().suite_name == current_test_->test_case().suite_name) {
      return;
    }
  }

  set_up_ts();
}

void Framework::TearDownTestSuiteIfNeeded(
    TearDownTestSuiteFunc tear_down_ts) const {
  if (tear_down_ts == Test::TearDownTestSuite) {
    return;
  }

  for (TestInfo* info = current_test_->next(); info != nullptr;
       info = info->next()) {
    if (info->test_case().suite_name == current_test_->test_case().suite_name) {
      return;
    }
  }

  tear_down_ts();
}

void Framework::StartTest(const TestInfo& test) {
  current_test_ = &test;
  current_result_ = TestResult::kSuccess;

  if (event_handler_ != nullptr) {
    event_handler_->TestCaseStart(test.test_case());
  }
}

void Framework::EndCurrentTest() {
  switch (current_result_) {
    case TestResult::kSuccess:
      run_tests_summary_.passed_tests++;
      break;
    case TestResult::kFailure:
      run_tests_summary_.failed_tests++;
      break;
    case TestResult::kSkipped:
      run_tests_summary_.skipped_tests++;
      break;
  }

  if (event_handler_ != nullptr) {
    event_handler_->TestCaseEnd(current_test_->test_case(), current_result_);
  }

  current_test_ = nullptr;
}

void Framework::CurrentTestSkip(int line) {
  if (current_result_ == TestResult::kSuccess) {
    current_result_ = TestResult::kSkipped;
  }
  return CurrentTestExpectSimple(
      "(test skipped)", "(test skipped)", line, true);
}

void Framework::CurrentTestExpectSimple(const char* expression,
                                        const char* evaluated_expression,
                                        int line,
                                        bool success) {
  PW_CHECK_NOTNULL(
      current_test_,
      "EXPECT/ASSERT was called when no test was running! EXPECT/ASSERT cannot "
      "be used from static constructors/destructors or before or after "
      "RUN_ALL_TESTS().");

  if (!success) {
    current_result_ = TestResult::kFailure;
    exit_status_ = 1;
  }

  if (event_handler_ == nullptr) {
    return;
  }

  TestExpectation expectation = {
      .expression = expression,
      .evaluated_expression = evaluated_expression,
      .line_number = line,
      .success = success,
  };

  event_handler_->TestCaseExpect(current_test_->test_case(), expectation);
}

bool Framework::ShouldRunTest(const TestInfo& test_info) const {
#if PW_CXX_STANDARD_IS_SUPPORTED(17)
  // Test suite filtering is only supported if using C++17.
  if (!test_suites_to_run_.empty()) {
    std::string_view test_suite(test_info.test_case().suite_name);

    bool suite_matches =
        std::any_of(test_suites_to_run_.begin(),
                    test_suites_to_run_.end(),
                    [&](auto& name) { return test_suite == name; });

    if (!suite_matches) {
      return false;
    }
  }
#endif  // PW_CXX_STANDARD_IS_SUPPORTED(17)

  return test_info.enabled();
}

bool TestInfo::enabled() const {
  constexpr size_t kStringSize = sizeof("DISABLED_") - 1;
  return std::strncmp("DISABLED_", test_case().test_name, kStringSize) != 0 &&
         std::strncmp("DISABLED_", test_case().suite_name, kStringSize) != 0;
}

}  // namespace internal
}  // namespace unit_test
}  // namespace pw
