// 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/arc_java_collector.h"

#include <ctime>
#include <memory>
#include <utility>

#include <base/bind.h>
#include <base/files/file.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/time/time.h>

#include "crash-reporter/arc_util.h"
#include "crash-reporter/util.h"

using base::File;
using base::FilePath;

namespace {

constexpr char kArcJavaCollectorName[] = "ARC_java";

}  // namespace

ArcJavaCollector::ArcJavaCollector()
    : CrashCollector(kArcJavaCollectorName,
                     kAlwaysUseUserCrashDirectory,
                     kNormalCrashSendMode,
                     kArcJavaCollectorName) {}

bool ArcJavaCollector::HandleCrash(
    const std::string& crash_type,
    const arc_util::BuildProperty& build_property,
    base::TimeDelta uptime) {
  std::ostringstream message;
  message << "Received " << crash_type << " notification";

  std::string contents;
  if (!base::ReadStreamToString(stdin, &contents)) {
    PLOG(ERROR) << "Failed to read crash log";
    return false;
  }
  if (contents.empty()) {
    LOG(ERROR) << "crash log was empty";
    return false;
  }

  CrashLogHeaderMap map;
  std::string exception_info, log;
  if (!arc_util::ParseCrashLog(crash_type, contents, &map, &exception_info,
                               &log)) {
    LOG(ERROR) << "Failed to parse crash log";
    return false;
  }

  const auto exec = arc_util::GetCrashLogHeader(map, arc_util::kProcessKey);
  message << " for " << exec;
  LogCrash(message.str(), "handling");

  bool out_of_capacity = false;
  if (!CreateReportForJavaCrash(crash_type, build_property, map, exception_info,
                                log, uptime, &out_of_capacity)) {
    if (!out_of_capacity) {
      EnqueueCollectionErrorLog(kErrorSystemIssue, exec);
    }
    return false;
  }

  return true;
}

std::string ArcJavaCollector::GetProductVersion() const {
  return arc_util::GetProductVersion();
}

void ArcJavaCollector::AddArcMetaData(const std::string& process,
                                      const std::string& crash_type,
                                      base::TimeDelta uptime) {
  for (const auto& metadata :
       arc_util::ListBasicARCRelatedMetadata(process, crash_type)) {
    AddCrashMetaUploadData(metadata.first, metadata.second);
  }
  AddCrashMetaUploadData(arc_util::kChromeOsVersionField, GetOsVersion());

#if USE_ARCPP
  if (uptime.is_zero()) {
    SetUpDBus();
    if (!arc_util::GetArcContainerUptime(session_manager_proxy_.get(),
                                         &uptime)) {
      uptime = base::TimeDelta();
    }
  }
#endif  // USE_ARCPP
  if (!uptime.is_zero()) {
    AddCrashMetaUploadData(arc_util::kUptimeField,
                           arc_util::FormatDuration(uptime));
  }

  if (arc_util::IsSilentReport(crash_type))
    AddCrashMetaData(arc_util::kSilentKey, "true");
}

bool ArcJavaCollector::CreateReportForJavaCrash(
    const std::string& crash_type,
    const arc_util::BuildProperty& build_property,
    const CrashLogHeaderMap& map,
    const std::string& exception_info,
    const std::string& log,
    base::TimeDelta uptime,
    bool* out_of_capacity) {
  FilePath crash_dir;
  if (!GetCreatedCrashDirectoryByEuid(geteuid(), &crash_dir, out_of_capacity)) {
    LOG(ERROR) << "Failed to create or find crash directory";
    return false;
  }

  const auto process = arc_util::GetCrashLogHeader(map, arc_util::kProcessKey);
  pid_t dt = arc_util::CreateRandomPID();
  const auto basename = FormatDumpBasename(process, std::time(nullptr), dt);
  const FilePath log_path = GetCrashPath(crash_dir, basename, "log");

  const int size = static_cast<int>(log.size());
  if (WriteNewFile(log_path, log) != size) {
    PLOG(ERROR) << "Failed to write log";
    return false;
  }

  AddArcMetaData(process, crash_type, uptime);
  for (auto metadata : arc_util::ListMetadataForBuildProperty(build_property)) {
    AddCrashMetaUploadData(metadata.first, metadata.second);
  }

  for (const auto& mapping : arc_util::kHeaderToFieldMapping) {
    if (map.count(mapping.first)) {
      AddCrashMetaUploadData(mapping.second,
                             arc_util::GetCrashLogHeader(map, mapping.first));
    }
  }

  if (exception_info.empty()) {
    if (const char* const tag = arc_util::GetSubjectTag(crash_type)) {
      std::ostringstream out;
      out << '[' << tag << ']';
      const auto it = map.find(arc_util::kSubjectKey);
      if (it != map.end())
        out << ' ' << it->second;

      AddCrashMetaData(arc_util::kSignatureField, out.str());
    } else {
      LOG(ERROR) << "Invalid crash type: " << crash_type;
      return false;
    }
  } else {
    const FilePath info_path = GetCrashPath(crash_dir, basename, "info");
    const int size = static_cast<int>(exception_info.size());

    if (WriteNewFile(info_path, exception_info) != size) {
      PLOG(ERROR) << "Failed to write exception info";
      return false;
    }

    AddCrashMetaUploadText(arc_util::kExceptionInfoField,
                           info_path.BaseName().value());
  }

  const FilePath meta_path = GetCrashPath(crash_dir, basename, "meta");
  FinishCrash(meta_path, process, log_path.BaseName().value());
  return true;
}

// static
CollectorInfo ArcJavaCollector::GetHandlerInfo(
    const std::string& arc_java_crash,
    const arc_util::BuildProperty& build_property,
    int64_t uptime_millis) {
  auto arc_java_collector = std::make_shared<ArcJavaCollector>();
  return {
      .collector = arc_java_collector,
      .handlers = {{
          // This handles Java app crashes of ARC++ and ARCVM.
          .should_handle = !arc_java_crash.empty(),
          .cb = base::BindRepeating(
              &ArcJavaCollector::HandleCrash, arc_java_collector,
              arc_java_crash, build_property,
              base::TimeDelta::FromMilliseconds(uptime_millis)),
      }},
  };
}
