// 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 "pw_unit_test/framework.h"

#include <algorithm>
#include <cstring>

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) {
  // 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() {
  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::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;
  }

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

  current_test_ = nullptr;
}

void Framework::ExpectationResult(const char* expression,
                                  const char* evaluated_expression,
                                  int line,
                                  bool success) {
  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) {
#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
