// Copyright 2021 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 "crash-reporter/security_anomaly_collector.h"

#include <memory>
#include <string>

#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>

#include "crash-reporter/constants.h"

namespace {
constexpr char kExecName[] = "security-anomaly";
constexpr char kMetadataKeyPrefix[] = "security_anomaly_";
constexpr char kSignatureKey[] = "sig";
}  // namespace

SecurityAnomalyCollector::SecurityAnomalyCollector()
    : CrashCollector("security_anomaly_collector"),
      anomaly_report_path_("/dev/stdin") {}

bool SecurityAnomalyCollector::LoadSecurityAnomaly(
    std::string* content,
    std::string* signature,
    std::map<std::string, std::string>* extra_metadata) {
  std::string anomaly_report;
  if (!base::ReadFileToString(anomaly_report_path_, &anomaly_report)) {
    PLOG(ERROR) << "Could not open " << anomaly_report_path_.value();
    return false;
  }

  // Report format
  // First line:  signature
  // Second line: parsed metadata key\x01value\x02key\x01value\x02
  // Third+ line: content

  std::string::size_type signature_end_position = anomaly_report.find('\n');
  if (signature_end_position == std::string::npos) {
    return false;
  }
  *signature = anomaly_report.substr(0, signature_end_position);

  anomaly_report = anomaly_report.substr(signature_end_position + 1);
  std::string::size_type metadata_end_position = anomaly_report.find('\n');
  if (metadata_end_position == std::string::npos) {
    return false;
  }
  *content = anomaly_report.substr(metadata_end_position + 1);

  base::StringPairs kvpairs;
  if (!base::SplitStringIntoKeyValuePairs(
          anomaly_report.substr(0, metadata_end_position), '\x01', '\x02',
          &kvpairs)) {
    return false;
  }

  for (const auto& kvpair : kvpairs) {
    extra_metadata->emplace(kMetadataKeyPrefix + kvpair.first, kvpair.second);
  }

  return !signature->empty();
}

bool SecurityAnomalyCollector::Collect(int32_t weight) {
  LOG(INFO) << "Processing security anomaly";

  if (weight != 1) {
    AddCrashMetaUploadData("weight", base::NumberToString(weight));
  }

  std::string signature;
  std::string content;
  std::map<std::string, std::string> extra_metadata;
  if (!LoadSecurityAnomaly(&content, &signature, &extra_metadata))
    return false;

  base::FilePath crash_directory;
  if (!GetCreatedCrashDirectoryByEuid(constants::kRootUid, &crash_directory,
                                      nullptr))
    return false;

  std::string dump_basename = FormatDumpBasename(kExecName, time(nullptr), 0);
  base::FilePath meta_path =
      GetCrashPath(crash_directory, dump_basename, "meta");
  base::FilePath log_path = GetCrashPath(crash_directory, dump_basename, "log");

  base::StringPiece file_content(content);
  if (WriteNewFile(log_path, file_content) !=
      static_cast<int>(file_content.length())) {
    PLOG(WARNING) << "Failed to write security anomaly to " << log_path.value();
    return false;
  }

  AddCrashMetaData(kSignatureKey, signature);

  for (const auto& metadata : extra_metadata)
    AddCrashMetaUploadData(metadata.first, metadata.second);

  FinishCrash(meta_path, kExecName, log_path.BaseName().value());

  return true;
}

// static
CollectorInfo SecurityAnomalyCollector::GetHandlerInfo(int32_t weight,
                                                       bool security_anomaly) {
  auto security_anomaly_collector =
      std::make_shared<SecurityAnomalyCollector>();
  return {.collector = security_anomaly_collector,
          .handlers = {{
              .should_handle = security_anomaly,
              .cb = base::BindRepeating(&SecurityAnomalyCollector::Collect,
                                        security_anomaly_collector, weight),
          }}};
}
