// Copyright 2017 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 "src/modular/lib/integration_testing/cpp/testing.h"

#include <fuchsia/testing/runner/cpp/fidl.h>
#include <lib/fit/function.h>
#include <lib/syslog/cpp/macros.h>

#include <set>

using fuchsia::testing::runner::TestRunner;
using fuchsia::testing::runner::TestRunnerPtr;
using fuchsia::testing::runner::TestRunnerStore;
using fuchsia::testing::runner::TestRunnerStorePtr;

namespace modular_testing {

namespace {
TestRunnerPtr g_test_runner;
TestRunnerStorePtr g_test_runner_store;
std::set<std::string> g_test_points;
bool g_connected;
}  // namespace

void Init(sys::ComponentContext* context, const std::string& identity) {
  FX_CHECK(context);
  FX_CHECK(!g_test_runner.is_bound());
  FX_CHECK(!g_test_runner_store.is_bound());

  g_test_runner = context->svc()->Connect<TestRunner>();
  g_test_runner.set_error_handler([](zx_status_t status) {
    if (g_connected) {
      FX_LOGS(ERROR) << "Lost connection to TestRunner. This indicates that "
                        "there was an observed process that was terminated "
                        "without calling TestRunner.Done().";
    } else {
      FX_LOGS(ERROR) << "This application must be run under test_runner.";
    }
    exit(1);
  });
  g_test_runner->Identify(identity, [] { g_connected = true; });
  g_test_runner->SetTestPointCount(g_test_points.size());
  g_test_runner_store = context->svc()->Connect<TestRunnerStore>();
}

void Fail(const std::string& log_msg) {
  if (g_test_runner.is_bound()) {
    g_test_runner->Fail(log_msg);
  }
}

void Done(fit::function<void()> ack) {
  if (g_test_runner.is_bound()) {
    g_test_runner->Done([ack = std::move(ack)] {
      ack();
      g_test_runner.Unbind();
    });
  } else {
    ack();
  }

  if (g_test_runner_store.is_bound()) {
    g_test_runner_store.Unbind();
  }
}

void Teardown(fit::function<void()> ack) {
  if (g_test_runner.is_bound()) {
    g_test_runner->Teardown([ack = std::move(ack)] {
      ack();
      g_test_runner.Unbind();
    });
  } else {
    ack();
  }

  if (g_test_runner_store.is_bound()) {
    g_test_runner_store.Unbind();
  }
}

TestRunnerStore* GetStore() {
  FX_CHECK(g_test_runner_store.is_bound());
  return g_test_runner_store.get();
}

void Put(const fidl::StringPtr& key, const fidl::StringPtr& value) {
  modular_testing::GetStore()->Put(key.value_or(""), value.value_or(""), [] {});
}

void Get(const fidl::StringPtr& key, fit::function<void(fidl::StringPtr)> callback) {
  modular_testing::GetStore()->Get(key.value_or(""), std::move(callback));
}

void Signal(const fidl::StringPtr& condition) {
  modular_testing::GetStore()->Put(condition.value_or(""), condition.value_or(""), [] {});
}

void Await(const fidl::StringPtr& condition, fit::function<void()> cont) {
  modular_testing::GetStore()->Get(condition.value_or(""),
                                   [cont = std::move(cont)](fidl::StringPtr) { cont(); });
}

void RegisterTestPoint(const std::string& label) {
  // Test points can only be registered before Init is called.
  FX_CHECK(!g_test_runner.is_bound()) << "Test Runner connection not bound. You must call "
                                      << "ComponentBase::TestInit() before registering "
                                      << "\"" << label << "\".";

  auto inserted = g_test_points.insert(label);

  // Test points must have unique labels.
  FX_CHECK(inserted.second) << "Test points must have unique labels. "
                            << "\"" << label << "\" is repeated.";
}

void PassTestPoint(const std::string& label) {
  // Test points can only be passed after initialization.
  FX_CHECK(g_test_runner.is_bound())
      << "Test Runner connection not bound. You must call "
      << "ComponentBase::TestInit() before \"" << label << "\".Pass() can be "
      << "called.";

  // Test points can only be passed once.
  FX_CHECK(g_test_points.erase(label)) << "TEST FAILED: Test point can only be passed once. "
                                       << "\"" << label << "\".Pass() has been called twice.";

  g_test_runner->PassTestPoint();
}

}  // namespace modular_testing
