// Copyright 2014 The Crashpad 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
//
//     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 "snapshot/mac/module_snapshot_mac.h"

#include <mach-o/loader.h>
#include <mach/mach.h>

#include "base/files/file_path.h"
#include "snapshot/mac/mach_o_image_annotations_reader.h"
#include "snapshot/mac/mach_o_image_reader.h"
#include "util/misc/tri_state.h"
#include "util/misc/uuid.h"
#include "util/stdlib/strnlen.h"

namespace crashpad {
namespace internal {

ModuleSnapshotMac::ModuleSnapshotMac()
    : ModuleSnapshot(),
      name_(),
      timestamp_(0),
      mach_o_image_reader_(nullptr),
      process_reader_(nullptr),
      initialized_() {}

ModuleSnapshotMac::~ModuleSnapshotMac() {}

bool ModuleSnapshotMac::Initialize(
    ProcessReaderMac* process_reader,
    const ProcessReaderMac::Module& process_reader_module) {
  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);

  process_reader_ = process_reader;
  name_ = process_reader_module.name;
  timestamp_ = process_reader_module.timestamp;
  mach_o_image_reader_ = process_reader_module.reader;
  if (!mach_o_image_reader_) {
    return false;
  }

  INITIALIZATION_STATE_SET_VALID(initialized_);
  return true;
}

void ModuleSnapshotMac::GetCrashpadOptions(CrashpadInfoClientOptions* options) {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  process_types::CrashpadInfo crashpad_info;
  if (!mach_o_image_reader_->GetCrashpadInfo(&crashpad_info)) {
    options->crashpad_handler_behavior = TriState::kUnset;
    options->system_crash_reporter_forwarding = TriState::kUnset;
    options->gather_indirectly_referenced_memory = TriState::kUnset;
    return;
  }

  options->crashpad_handler_behavior =
      CrashpadInfoClientOptions::TriStateFromCrashpadInfo(
          crashpad_info.crashpad_handler_behavior);

  options->system_crash_reporter_forwarding =
      CrashpadInfoClientOptions::TriStateFromCrashpadInfo(
          crashpad_info.system_crash_reporter_forwarding);

  options->gather_indirectly_referenced_memory =
      CrashpadInfoClientOptions::TriStateFromCrashpadInfo(
          crashpad_info.gather_indirectly_referenced_memory);

  options->indirectly_referenced_memory_cap =
      crashpad_info.indirectly_referenced_memory_cap;
}

std::string ModuleSnapshotMac::Name() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return name_;
}

uint64_t ModuleSnapshotMac::Address() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return mach_o_image_reader_->Address();
}

uint64_t ModuleSnapshotMac::Size() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return mach_o_image_reader_->Size();
}

time_t ModuleSnapshotMac::Timestamp() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return timestamp_;
}

void ModuleSnapshotMac::FileVersion(uint16_t* version_0,
                                    uint16_t* version_1,
                                    uint16_t* version_2,
                                    uint16_t* version_3) const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  if (mach_o_image_reader_->FileType() == MH_DYLIB) {
    uint32_t dylib_version = mach_o_image_reader_->DylibVersion();
    *version_0 = (dylib_version & 0xffff0000) >> 16;
    *version_1 = (dylib_version & 0x0000ff00) >> 8;
    *version_2 = (dylib_version & 0x000000ff);
    *version_3 = 0;
  } else {
    *version_0 = 0;
    *version_1 = 0;
    *version_2 = 0;
    *version_3 = 0;
  }
}

void ModuleSnapshotMac::SourceVersion(uint16_t* version_0,
                                      uint16_t* version_1,
                                      uint16_t* version_2,
                                      uint16_t* version_3) const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  // LC_SOURCE_VERSION is supposed to be interpreted as a 5-component version
  // number, 24 bits for the first component and 10 for the others, per
  // <mach-o/loader.h>. To preserve the full range of possible version numbers
  // without data loss, map it to the 4 16-bit fields mandated by the interface
  // here, which was informed by the minidump file format.
  uint64_t source_version = mach_o_image_reader_->SourceVersion();
  *version_0 = (source_version & 0xffff000000000000u) >> 48;
  *version_1 = (source_version & 0x0000ffff00000000u) >> 32;
  *version_2 = (source_version & 0x00000000ffff0000u) >> 16;
  *version_3 = source_version & 0x000000000000ffffu;
}

ModuleSnapshot::ModuleType ModuleSnapshotMac::GetModuleType() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  uint32_t file_type = mach_o_image_reader_->FileType();
  switch (file_type) {
    case MH_EXECUTE:
      return kModuleTypeExecutable;
    case MH_DYLIB:
      return kModuleTypeSharedLibrary;
    case MH_DYLINKER:
      return kModuleTypeDynamicLoader;
    case MH_BUNDLE:
      return kModuleTypeLoadableModule;
    default:
      return kModuleTypeUnknown;
  }
}

void ModuleSnapshotMac::UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  mach_o_image_reader_->UUID(uuid);
  *age = 0;
}

std::string ModuleSnapshotMac::DebugFileName() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return base::FilePath(Name()).BaseName().value();
}

std::vector<uint8_t> ModuleSnapshotMac::BuildID() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return std::vector<uint8_t>();
}

std::vector<std::string> ModuleSnapshotMac::AnnotationsVector() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  MachOImageAnnotationsReader annotations_reader(
      process_reader_, mach_o_image_reader_, name_);
  return annotations_reader.Vector();
}

std::map<std::string, std::string> ModuleSnapshotMac::AnnotationsSimpleMap()
    const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  MachOImageAnnotationsReader annotations_reader(
      process_reader_, mach_o_image_reader_, name_);
  return annotations_reader.SimpleMap();
}

std::vector<AnnotationSnapshot> ModuleSnapshotMac::AnnotationObjects() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  MachOImageAnnotationsReader annotations_reader(
      process_reader_, mach_o_image_reader_, name_);
  return annotations_reader.AnnotationsList();
}

std::set<CheckedRange<uint64_t>> ModuleSnapshotMac::ExtraMemoryRanges() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return std::set<CheckedRange<uint64_t>>();
}

std::vector<const UserMinidumpStream*>
ModuleSnapshotMac::CustomMinidumpStreams() const {
  return std::vector<const UserMinidumpStream*>();
}

}  // namespace internal
}  // namespace crashpad
