/* Copyright 2019 The Chromium OS 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 "hardware_verifier/cli.h"

#include <iostream>
#include <optional>
#include <sstream>
#include <string>
#include <utility>

#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/notreached.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/util/json_util.h>
#include <runtime_probe/proto_bindings/runtime_probe.pb.h>

#include "hardware_verifier/hardware_verifier.pb.h"
#include "hardware_verifier/hw_verification_report_getter_impl.h"
#include "hardware_verifier/observer.h"

namespace hardware_verifier {

namespace {

using ReportGetterErrorCode = HwVerificationReportGetter::ErrorCode;

CLIVerificationResult
ConvertHwVerificationReportGetterErrorCodeToCLIVerificationResult(
    ReportGetterErrorCode error_code) {
  switch (error_code) {
    case ReportGetterErrorCode::kErrorCodeMissingDefaultHwVerificationSpecFile:
      return CLIVerificationResult::kSkippedVerification;
    case ReportGetterErrorCode::kErrorCodeInvalidHwVerificationSpecFile:
      return CLIVerificationResult::kInvalidHwVerificationSpecFile;
    case ReportGetterErrorCode::kErrorCodeInvalidProbeResultFile:
      return CLIVerificationResult::kInvalidProbeResultFile;
    case ReportGetterErrorCode::kErrorCodeProbeFail:
      return CLIVerificationResult::kProbeFail;
    case ReportGetterErrorCode::
        kErrorCodeProbeResultHwVerificationSpecMisalignment:
      return CLIVerificationResult::kProbeResultHwVerificationSpecMisalignment;
    case ReportGetterErrorCode::kErrorCodeNoError:
    default:
      NOTREACHED() << "Invalid HwVerificationReportGetter::ErrorCode: "
                   << static_cast<int>(error_code);
      return CLIVerificationResult::kUnknownError;
  }
}

std::optional<std::string> OutputInTextFormat(
    HwVerificationReport hw_verification_report, bool pii) {
  std::stringstream ss;
  const auto generic_device_info = hw_verification_report.generic_device_info();
  hw_verification_report.clear_generic_device_info();

  // Output the AVL qualification status in JSON format.
  auto json_print_opts = google::protobuf::util::JsonPrintOptions();
  json_print_opts.add_whitespace = true;
  json_print_opts.always_print_primitive_fields = true;
  std::string json_output_data;
  const auto convert_status = google::protobuf::util::MessageToJsonString(
      hw_verification_report, &json_output_data, json_print_opts);
  if (!convert_status.ok()) {
    LOG(ERROR) << "Failed to output the qualification report in JSON: "
               << convert_status.ToString() << ".";
    return std::nullopt;
  }
  ss << "[Component Qualification Status]\n" << json_output_data;

  if (pii) {
    // Output the generic device info in prototxt format.
    ss << "\n[Generic Device Info]\n";
    // Enclose google::protobuf::io::OstreamOutputStream in another nested
    // scope so that its data will be flushed while being destroyed.
    google::protobuf::io::OstreamOutputStream ostream_output_stream{&ss};
    if (!google::protobuf::TextFormat::Print(generic_device_info,
                                             &ostream_output_stream)) {
      LOG(ERROR)
          << "Failed to output the generic device info in prototxt format.";
      return std::nullopt;
    }
  }
  return ss.str();
}

}  // namespace

CLI::CLI()
    : vr_getter_(std::make_unique<HwVerificationReportGetterImpl>()),
      output_stream_(&std::cout) {}

CLIVerificationResult CLI::Run(const std::string& probe_result_file,
                               const std::string& hw_verification_spec_file,
                               const CLIOutputFormat output_format,
                               bool pii) {
  ReportGetterErrorCode error_code;
  auto hw_verification_report = vr_getter_->Get(
      probe_result_file, hw_verification_spec_file, &error_code);
  if (error_code != ReportGetterErrorCode::kErrorCodeNoError) {
    return ConvertHwVerificationReportGetterErrorCodeToCLIVerificationResult(
        error_code);
  }

  if (!pii) {
    // Remove PII data.
    for (auto& mutable_component :
         *(hw_verification_report->mutable_found_component_infos())) {
      mutable_component.clear_component_uuid();
    }
    hw_verification_report->clear_generic_device_info();
  }

  LOG(INFO) << "Output the report.";
  switch (output_format) {
    case CLIOutputFormat::kProtoBin: {
      std::string s;
      if (!hw_verification_report->SerializeToString(&s)) {
        return CLIVerificationResult::kUnknownError;
      }
      LOG(INFO) << "Output the report in protobuf binary format, " << s.size()
                << "bytes.";
      *output_stream_ << s;
      break;
    }
    case CLIOutputFormat::kText: {
      auto output_data = OutputInTextFormat(*hw_verification_report, pii);
      if (!output_data.has_value()) {
        return CLIVerificationResult::kUnknownError;
      }
      LOG(INFO) << "Output the report in text format:";
      LOG(INFO) << output_data.value();
      *output_stream_ << output_data.value();
    }
  }

  LOG(INFO) << "Send to Observer.";
  auto observer = Observer::GetInstance();
  observer->RecordHwVerificationReport(*hw_verification_report);

  return (hw_verification_report->is_compliant()
              ? CLIVerificationResult::kPass
              : CLIVerificationResult::kFail);
}

}  // namespace hardware_verifier
