// Copyright 2019 The Crashpad Authors. All rights reserved.
//
// 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
//
//     http://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 "handler/linux/capture_snapshot.h"

#include <utility>

#include "snapshot/crashpad_info_client_options.h"
#include "snapshot/sanitized/sanitization_information.h"
#include "util/misc/metrics.h"
#include "util/misc/tri_state.h"

namespace crashpad {

bool CaptureSnapshot(
    PtraceConnection* connection,
    const ExceptionHandlerProtocol::ClientInformation& info,
    const std::map<std::string, std::string>& process_annotations,
    uid_t client_uid,
    VMAddress requesting_thread_stack_address,
    pid_t* requesting_thread_id,
    std::unique_ptr<ProcessSnapshotLinux>* snapshot,
    std::unique_ptr<ProcessSnapshotSanitized>* sanitized_snapshot
#if defined(STARBOARD)
    ,
    VMAddress evergreen_information_address,
    VMAddress annotations_address
#endif
    ) {
  std::unique_ptr<ProcessSnapshotLinux> process_snapshot(
      new ProcessSnapshotLinux());
#if defined(STARBOARD)
  if (!process_snapshot->Initialize(
          connection, evergreen_information_address, annotations_address)) {
#else
  if (!process_snapshot->Initialize(connection)) {
#endif
    Metrics::ExceptionCaptureResult(Metrics::CaptureResult::kSnapshotFailed);
    return false;
  }

  pid_t local_requesting_thread_id = -1;
  if (requesting_thread_stack_address) {
    local_requesting_thread_id = process_snapshot->FindThreadWithStackAddress(
        requesting_thread_stack_address);
  }

  if (requesting_thread_id) {
    *requesting_thread_id = local_requesting_thread_id;
  }

  if (!process_snapshot->InitializeException(info.exception_information_address,
                                             local_requesting_thread_id)) {
    Metrics::ExceptionCaptureResult(
        Metrics::CaptureResult::kExceptionInitializationFailed);
    return false;
  }

  Metrics::ExceptionCode(process_snapshot->Exception()->Exception());

  CrashpadInfoClientOptions client_options;
  process_snapshot->GetCrashpadOptions(&client_options);
  if (client_options.crashpad_handler_behavior == TriState::kDisabled) {
    return false;
  }

  for (auto& p : process_annotations) {
    process_snapshot->AddAnnotation(p.first, p.second);
  }

  if (info.sanitization_information_address) {
    SanitizationInformation sanitization_info;
    ProcessMemoryRange range;
    if (!range.Initialize(connection->Memory(), connection->Is64Bit()) ||
        !range.Read(info.sanitization_information_address,
                    sizeof(sanitization_info),
                    &sanitization_info)) {
      Metrics::ExceptionCaptureResult(
          Metrics::CaptureResult::kSanitizationInitializationFailed);
      return false;
    }

    auto annotations_whitelist = std::make_unique<std::vector<std::string>>();
    auto memory_range_whitelist =
        std::make_unique<std::vector<std::pair<VMAddress, VMAddress>>>();
    if (!ReadAnnotationsWhitelist(
            range,
            sanitization_info.annotations_whitelist_address,
            annotations_whitelist.get()) ||
        !ReadMemoryRangeWhitelist(
            range,
            sanitization_info.memory_range_whitelist_address,
            memory_range_whitelist.get())) {
      Metrics::ExceptionCaptureResult(
          Metrics::CaptureResult::kSanitizationInitializationFailed);
      return false;
    }

    std::unique_ptr<ProcessSnapshotSanitized> sanitized(
        new ProcessSnapshotSanitized());
    if (!sanitized->Initialize(process_snapshot.get(),
                               sanitization_info.annotations_whitelist_address
                                   ? std::move(annotations_whitelist)
                                   : nullptr,
                               std::move(memory_range_whitelist),
                               sanitization_info.target_module_address,
                               sanitization_info.sanitize_stacks)) {
      Metrics::ExceptionCaptureResult(
          Metrics::CaptureResult::kSkippedDueToSanitization);
      return false;
    }
    *sanitized_snapshot = std::move(sanitized);
  }

  *snapshot = std::move(process_snapshot);
  return true;
}

}  // namespace crashpad
