// Copyright 2020 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/unit_test_service.h"

#include "pw_containers/vector.h"
#include "pw_log/log.h"
#include "pw_protobuf/decoder.h"
#include "pw_unit_test/framework.h"

namespace pw::unit_test {

void UnitTestService::Run(ServerContext&,
                          ConstByteSpan request,
                          RawServerWriter& writer) {
  writer_ = std::move(writer);
  verbose_ = false;

  // List of test suite names to run. The string views in this vector point to
  // data in the raw protobuf request message, so it is only valid for the
  // duration of this function.
  pw::Vector<std::string_view, 16> suites_to_run;

  protobuf::Decoder decoder(request);

  Status status;
  while ((status = decoder.Next()).ok()) {
    switch (static_cast<TestRunRequest::Fields>(decoder.FieldNumber())) {
      case TestRunRequest::Fields::REPORT_PASSED_EXPECTATIONS:
        decoder.ReadBool(&verbose_)
            .IgnoreError();  // TODO(pwbug/387): Handle Status properly
        break;

      case TestRunRequest::Fields::TEST_SUITE: {
        std::string_view suite_name;
        if (!decoder.ReadString(&suite_name).ok()) {
          break;
        }

        if (!suites_to_run.full()) {
          suites_to_run.push_back(suite_name);
        } else {
          PW_LOG_ERROR("Maximum of %u test suite filters supported",
                       static_cast<unsigned>(suites_to_run.max_size()));
          writer_.Finish(Status::InvalidArgument())
              .IgnoreError();  // TODO(pwbug/387): Handle Status properly
          return;
        }

        break;
      }
    }
  }

  if (status != Status::OutOfRange()) {
    writer_.Finish(status)
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
    return;
  }

  PW_LOG_INFO("Starting unit test run");

  RegisterEventHandler(&handler_);
  SetTestSuitesToRun(suites_to_run);
  PW_LOG_DEBUG("%u test suite filters applied",
               static_cast<unsigned>(suites_to_run.size()));

  RUN_ALL_TESTS();

  RegisterEventHandler(nullptr);
  SetTestSuitesToRun({});

  PW_LOG_INFO("Unit test run complete");

  writer_.Finish().IgnoreError();  // TODO(pwbug/387): Handle Status properly
}

void UnitTestService::WriteTestRunStart() {
  // Write out the key for the start field (even though the message is empty).
  WriteEvent(
      [&](Event::StreamEncoder& event) { event.GetTestRunStartEncoder(); });
}

void UnitTestService::WriteTestRunEnd(const RunTestsSummary& summary) {
  WriteEvent([&](Event::StreamEncoder& event) {
    TestRunEnd::StreamEncoder test_run_end = event.GetTestRunEndEncoder();
    test_run_end.WritePassed(summary.passed_tests)
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
    test_run_end.WriteFailed(summary.failed_tests)
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
    test_run_end.WriteSkipped(summary.skipped_tests)
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
    test_run_end.WriteDisabled(summary.disabled_tests)
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
  });
}

void UnitTestService::WriteTestCaseStart(const TestCase& test_case) {
  WriteEvent([&](Event::StreamEncoder& event) {
    TestCaseDescriptor::StreamEncoder descriptor =
        event.GetTestCaseStartEncoder();
    descriptor.WriteSuiteName(test_case.suite_name)
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
    descriptor.WriteTestName(test_case.test_name)
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
    descriptor.WriteFileName(test_case.file_name)
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
  });
}

void UnitTestService::WriteTestCaseEnd(TestResult result) {
  WriteEvent([&](Event::StreamEncoder& event) {
    event.WriteTestCaseEnd(static_cast<TestCaseResult>(result))
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
  });
}

void UnitTestService::WriteTestCaseDisabled(const TestCase& test_case) {
  WriteEvent([&](Event::StreamEncoder& event) {
    TestCaseDescriptor::StreamEncoder descriptor =
        event.GetTestCaseDisabledEncoder();
    descriptor.WriteSuiteName(test_case.suite_name)
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
    descriptor.WriteTestName(test_case.test_name)
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
    descriptor.WriteFileName(test_case.file_name)
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
  });
}

void UnitTestService::WriteTestCaseExpectation(
    const TestExpectation& expectation) {
  if (!verbose_ && expectation.success) {
    return;
  }

  WriteEvent([&](Event::StreamEncoder& event) {
    TestCaseExpectation::StreamEncoder test_case_expectation =
        event.GetTestCaseExpectationEncoder();
    test_case_expectation.WriteExpression(expectation.expression)
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
    test_case_expectation
        .WriteEvaluatedExpression(expectation.evaluated_expression)
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
    test_case_expectation.WriteLineNumber(expectation.line_number)
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
    test_case_expectation.WriteSuccess(expectation.success)
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
  });
}

}  // namespace pw::unit_test
