// Copyright 2019 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 "test_suite.h"

#include <fuchsia/test/cpp/fidl.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/errors.h>

#include <measure_tape/hlcpp/measure_tape_for_case.h>

#include "lib/fidl/cpp/clone.h"

namespace example {

using fuchsia::test::Case;
using fuchsia::test::Result;

TestSuite::TestSuite(async::Loop* loop, std::vector<TestInput> inputs, Options options)
    : binding_(this), test_inputs_(std::move(inputs)), options_(options), loop_(loop) {
  for (auto& test_input : test_inputs_) {
    if (test_input.disabled) {
      disabled_tests_.insert(test_input.name);
    }
  }
}

void TestSuite::GetTests(::fidl::InterfaceRequest<fuchsia::test::CaseIterator> request) {
  if (options_.close_channel_get_tests) {
    binding_.Close(ZX_ERR_PEER_CLOSED);
    return;
  }
  if (options_.dont_service_get_tests) {
    return;
  }

  std::vector<Case> cases;

  for (auto& test_input : test_inputs_) {
    Case test_case;
    test_case.set_name(test_input.name);
    test_case.set_enabled(!test_input.disabled);
    cases.push_back(std::move(test_case));
  }

  auto service = std::make_unique<CaseIterator>(
      test_inputs_, [this](CaseIterator* ptr) { case_iterator_bindings_.RemoveBinding(ptr); });
  case_iterator_bindings_.AddBinding(std::move(service), std::move(request));
}

void TestSuite::Run(std::vector<fuchsia::test::Invocation> tests,
                    fuchsia::test::RunOptions run_options,
                    fidl::InterfaceHandle<fuchsia::test::RunListener> run_listener) {
  if (options_.close_channel_run) {
    binding_.Close(ZX_ERR_PEER_CLOSED);
    return;
  }
  if (options_.dont_service_run) {
    return;
  }
  fuchsia::test::RunListenerPtr ptr;
  ptr.Bind(std::move(run_listener));
  for (auto& test_invocation : tests) {
    const auto& test_name = test_invocation.name();
    zx::socket stdout_sock, stderr_sock, case_stdout, case_stderr;
    zx::socket::create(0, &stdout_sock, &case_stdout);
    zx::socket::create(0, &stderr_sock, &case_stderr);
    fuchsia::test::CaseListenerPtr case_list_ptr;
    fuchsia::test::StdHandles std_handles;
    std_handles.set_out(std::move(stdout_sock));
    std_handles.set_err(std::move(stderr_sock));
    ptr->OnTestCaseStarted(fidl::Clone(test_invocation), std::move(std_handles),
                           case_list_ptr.NewRequest());
    const bool should_skip_test = ShouldSkipTest(run_options, test_name);
    if (!should_skip_test) {
      std::string msg1 = "log1 for " + test_name + "\n";
      std::string msg2 = "log2 for " + test_name + "\n";
      std::string msg3 = "log3 for " + test_name + "\n";
      zx_status_t status;
      FX_CHECK(ZX_OK == (status = case_stdout.write(0, msg1.data(), msg1.length(), nullptr)))
          << status;
      FX_CHECK(ZX_OK == (status = case_stdout.write(0, msg2.data(), msg2.length(), nullptr)))
          << status;
      FX_CHECK(ZX_OK == (status = case_stdout.write(0, msg3.data(), msg3.length(), nullptr)))
          << status;
      for (auto& test_input : test_inputs_) {
        if (test_input.name == test_name) {
          if (test_input.write_stderr_logs) {
            std::string msg1 = "stderr msg1 for " + test_name + "\n";
            std::string msg2 = "stderr msg2 for " + test_name + "\n";
            FX_CHECK(ZX_OK == (status = case_stderr.write(0, msg1.data(), msg1.length(), nullptr)))
                << status;
            FX_CHECK(ZX_OK == (status = case_stderr.write(0, msg2.data(), msg2.length(), nullptr)))
                << status;
          }
        }
      }
    }
    Result result;

    bool send_finished_event = true;
    for (auto& test_input : test_inputs_) {
      if (test_input.name == test_name) {
        if (test_input.set_result_status) {
          result.set_status(should_skip_test ? fuchsia::test::Status::SKIPPED : test_input.status);
        }
        send_finished_event = !test_input.incomplete_test;
        break;
      }
    }
    if (send_finished_event) {
      case_list_ptr->Finished(std::move(result));
    }
  }
  if (!options_.dont_send_on_finish_event) {
    ptr->OnFinished();
  }
}

bool TestSuite::ShouldSkipTest(const fuchsia::test::RunOptions& run_options,
                               const std::string& test_name) const {
  // Disabled tests are excluded && this test is disabled.
  return !run_options.include_disabled_tests() &&
         (disabled_tests_.find(test_name) != disabled_tests_.end());
}

fidl::InterfaceRequestHandler<fuchsia::test::Suite> TestSuite::GetHandler() {
  auto handler = [this](fidl::InterfaceRequest<fuchsia::test::Suite> request) {
    binding_.Bind(std::move(request));
  };

  binding_.set_error_handler([this](zx_status_t /*unused*/) { loop_->Shutdown(); });
  return handler;
}

void CaseIterator::GetNext(GetNextCallback callback) {
  const size_t page_overhead = sizeof(fidl_message_header_t) + sizeof(fidl_vector_t);
  const size_t max_bytes = ZX_CHANNEL_MAX_MSG_BYTES - page_overhead;
  size_t bytes_used = 0;

  std::vector<Case> cases;
  // Send the next page of Cases
  for (; iter_ < test_inputs_.end(); iter_++) {
    Case test_case;
    test_case.set_name(iter_->name);
    bytes_used += measure_tape::fuchsia::test::Measure(test_case).num_bytes;
    if (bytes_used > max_bytes) {
      break;
    }
    cases.emplace_back(std::move(test_case));
  }
  callback(std::move(cases));

  if (bytes_used == 0) {
    done_callback_(this);
  }
}

}  // namespace example
