// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <zircon/assert.h>

#include <algorithm>
#include <cstdlib>
#include <memory>
#include <utility>

#include <fbl/auto_call.h>
#include <zxtest/base/test-case.h>
#include <zxtest/base/types.h>

namespace zxtest {

namespace {

using internal::SetUpTestCaseFn;
using internal::TearDownTestCaseFn;
using internal::TestDriver;
using internal::TestStatus;

}  // namespace

TestCase::TestCase(const fbl::String& name, SetUpTestCaseFn set_up, TearDownTestCaseFn tear_down)
    : name_(name), set_up_(std::move(set_up)), tear_down_(std::move(tear_down)) {
  ZX_ASSERT_MSG(set_up_, "Invalid SetUpTestCaseFn");
  ZX_ASSERT_MSG(tear_down_, "Invalid TearDownTestCaseFn");
}
TestCase::TestCase(TestCase&& other) = default;
TestCase::~TestCase() = default;

size_t TestCase::TestCount() const { return test_infos_.size(); }

size_t TestCase::MatchingTestCount() const { return selected_indexes_.size(); }

void TestCase::Filter(TestCase::FilterFn filter) {
  fbl::Vector<unsigned long> filtered_indexes;
  filtered_indexes.reserve(test_infos_.size());
  for (unsigned long i = 0; i < test_infos_.size(); ++i) {
    const auto& test_info = test_infos_[i];
    if (!filter || filter(name_, test_info.name())) {
      filtered_indexes.push_back(i);
    }
  }
  selected_indexes_.swap(filtered_indexes);
}

void TestCase::Shuffle(uint32_t random_seed) {
  for (unsigned long i = 1; i < selected_indexes_.size(); ++i) {
    unsigned long j = rand_r(&random_seed) % (i + 1);
    if (j != i) {
      std::swap(selected_indexes_[i], selected_indexes_[j]);
    }
  }
}

void TestCase::UnShuffle() {
  for (unsigned long i = 0; i < selected_indexes_.size(); ++i) {
    selected_indexes_[i] = i;
  }
}

bool TestCase::RegisterTest(const fbl::String& name, const SourceLocation& location,
                            internal::TestFactory factory) {
  auto it = std::find_if(test_infos_.begin(), test_infos_.end(),
                         [&name](const TestInfo& info) { return info.name() == name; });

  // Test already registered.
  if (it != test_infos_.end()) {
    return false;
  }

  selected_indexes_.push_back(selected_indexes_.size());
  test_infos_.push_back(TestInfo(name, location, std::move(factory)));
  return true;
}

void TestCase::Run(LifecycleObserver* event_broadcaster, TestDriver* driver) {
  if (selected_indexes_.size() == 0) {
    return;
  }

  auto tear_down = fbl::MakeAutoCall([this, event_broadcaster] {
    tear_down_();
    event_broadcaster->OnTestCaseEnd(*this);
  });
  event_broadcaster->OnTestCaseStart(*this);
  set_up_();

  if (!driver->Continue()) {
    return;
  }

  for (unsigned long i = 0; i < selected_indexes_.size(); ++i) {
    const auto& test_info = test_infos_[selected_indexes_[i]];
    {
      // This block enforces that the destructor is called before
      // completing the test, for accurate error reporting.
      // This prevents buggy destructors from crashing after a test completed,
      // marking it as a success.
      event_broadcaster->OnTestStart(*this, test_info);
      std::unique_ptr<Test> test = test_info.Instantiate(driver);
      test->Run();
    }
    switch (driver->Status()) {
      case TestStatus::kPassed:
        event_broadcaster->OnTestSuccess(*this, test_info);
        break;
      case TestStatus::kSkipped:
        event_broadcaster->OnTestSkip(*this, test_info);
        break;
      case TestStatus::kFailed:
        event_broadcaster->OnTestFailure(*this, test_info);
        if (return_on_failure_) {
          return;
        }
        break;
      default:
        break;
    }
  }
}

}  // namespace zxtest
