// 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.

#ifndef CRASHPAD_MINIDUMP_MINIDUMP_SYSTEM_INFO_WRITER_H_
#define CRASHPAD_MINIDUMP_MINIDUMP_SYSTEM_INFO_WRITER_H_

#include <windows.h>
#include <dbghelp.h>
#include <stdint.h>
#include <sys/types.h>

#include <memory>
#include <string>
#include <vector>

#include "minidump/minidump_extensions.h"
#include "minidump/minidump_stream_writer.h"
#include "minidump/minidump_writable.h"

namespace crashpad {

class SystemSnapshot;

namespace internal {
class MinidumpUTF16StringWriter;
}  // namespace internal

//! \brief The writer for a MINIDUMP_SYSTEM_INFO stream in a minidump file.
class MinidumpSystemInfoWriter final : public internal::MinidumpStreamWriter {
 public:
  MinidumpSystemInfoWriter();

  MinidumpSystemInfoWriter(const MinidumpSystemInfoWriter&) = delete;
  MinidumpSystemInfoWriter& operator=(const MinidumpSystemInfoWriter&) = delete;

  ~MinidumpSystemInfoWriter() override;

  //! \brief Initializes MINIDUMP_SYSTEM_INFO based on \a system_snapshot.
  //!
  //! \param[in] system_snapshot The system snapshot to use as source data.
  //!
  //! \note Valid in #kStateMutable. No mutator methods may be called before
  //!     this method, and it is not normally necessary to call any mutator
  //!     methods after this method.
  void InitializeFromSnapshot(const SystemSnapshot* system_snapshot);

  //! \brief Sets MINIDUMP_SYSTEM_INFO::ProcessorArchitecture.
  void SetCPUArchitecture(MinidumpCPUArchitecture processor_architecture) {
    system_info_.ProcessorArchitecture = processor_architecture;
  }

  //! \brief Sets MINIDUMP_SYSTEM_INFO::ProcessorLevel and
  //!     MINIDUMP_SYSTEM_INFO::ProcessorRevision.
  void SetCPULevelAndRevision(uint16_t processor_level,
                              uint16_t processor_revision) {
    system_info_.ProcessorLevel = processor_level;
    system_info_.ProcessorRevision = processor_revision;
  }

  //! \brief Sets MINIDUMP_SYSTEM_INFO::NumberOfProcessors.
  void SetCPUCount(uint8_t number_of_processors) {
    system_info_.NumberOfProcessors = number_of_processors;
  }

  //! \brief Sets MINIDUMP_SYSTEM_INFO::PlatformId.
  void SetOS(MinidumpOS platform_id) { system_info_.PlatformId = platform_id; }

  //! \brief Sets MINIDUMP_SYSTEM_INFO::ProductType.
  void SetOSType(MinidumpOSType product_type) {
    system_info_.ProductType = product_type;
  }

  //! \brief Sets MINIDUMP_SYSTEM_INFO::MajorVersion,
  //!     MINIDUMP_SYSTEM_INFO::MinorVersion, and
  //!     MINIDUMP_SYSTEM_INFO::BuildNumber.
  void SetOSVersion(uint32_t major_version,
                    uint32_t minor_version,
                    uint32_t build_number) {
    system_info_.MajorVersion = major_version;
    system_info_.MinorVersion = minor_version;
    system_info_.BuildNumber = build_number;
  }

  //! \brief Arranges for MINIDUMP_SYSTEM_INFO::CSDVersionRva to point to a
  //!     MINIDUMP_STRING containing the supplied string.
  //!
  //! This method must be called prior to Freeze(). A CSD version is required
  //! in all MINIDUMP_SYSTEM_INFO streams. An empty string is an acceptable
  //! value.
  void SetCSDVersion(const std::string& csd_version);

  //! \brief Sets MINIDUMP_SYSTEM_INFO::SuiteMask.
  void SetSuiteMask(uint16_t suite_mask) {
    system_info_.SuiteMask = suite_mask;
  }

  //! \brief Sets \ref CPU_INFORMATION::VendorId
  //!     "MINIDUMP_SYSTEM_INFO::Cpu::X86CpuInfo::VendorId".
  //!
  //! This is only valid if SetCPUArchitecture() has been used to set the CPU
  //! architecture to #kMinidumpCPUArchitectureX86 or
  //! #kMinidumpCPUArchitectureX86Win64.
  //!
  //! \param[in] ebx The first 4 bytes of the CPU vendor string, the value
  //!     reported in `cpuid 0` `ebx`.
  //! \param[in] edx The middle 4 bytes of the CPU vendor string, the value
  //!     reported in `cpuid 0` `edx`.
  //! \param[in] ecx The last 4 bytes of the CPU vendor string, the value
  //!     reported by `cpuid 0` `ecx`.
  //!
  //! \note Do not call this method if SetCPUArchitecture() has been used to set
  //!     the CPU architecture to #kMinidumpCPUArchitectureAMD64.
  //!
  //! \sa SetCPUX86VendorString()
  void SetCPUX86Vendor(uint32_t ebx, uint32_t edx, uint32_t ecx);

  //! \brief Sets \ref CPU_INFORMATION::VendorId
  //!     "MINIDUMP_SYSTEM_INFO::Cpu::X86CpuInfo::VendorId".
  //!
  //! This is only valid if SetCPUArchitecture() has been used to set the CPU
  //! architecture to #kMinidumpCPUArchitectureX86 or
  //! #kMinidumpCPUArchitectureX86Win64.
  //!
  //! \param[in] vendor The entire CPU vendor string, which must be exactly 12
  //!     bytes long.
  //!
  //! \note Do not call this method if SetCPUArchitecture() has been used to set
  //!     the CPU architecture to #kMinidumpCPUArchitectureAMD64.
  //!
  //! \sa SetCPUX86Vendor()
  void SetCPUX86VendorString(const std::string& vendor);

  //! \brief Sets \ref CPU_INFORMATION::VersionInformation
  //!     "MINIDUMP_SYSTEM_INFO::Cpu::X86CpuInfo::VersionInformation" and
  //!     \ref CPU_INFORMATION::FeatureInformation
  //!     "MINIDUMP_SYSTEM_INFO::Cpu::X86CpuInfo::FeatureInformation".
  //!
  //! This is only valid if SetCPUArchitecture() has been used to set the CPU
  //! architecture to #kMinidumpCPUArchitectureX86 or
  //! #kMinidumpCPUArchitectureX86Win64.
  //!
  //! \note Do not call this method if SetCPUArchitecture() has been used to set
  //!     the CPU architecture to #kMinidumpCPUArchitectureAMD64.
  void SetCPUX86VersionAndFeatures(uint32_t version, uint32_t features);

  //! \brief Sets \ref CPU_INFORMATION::AMDExtendedCpuFeatures
  //!     "MINIDUMP_SYSTEM_INFO::Cpu::X86CpuInfo::AMDExtendedCPUFeatures".
  //!
  //! This is only valid if SetCPUArchitecture() has been used to set the CPU
  //! architecture to #kMinidumpCPUArchitectureX86 or
  //! #kMinidumpCPUArchitectureX86Win64, and if SetCPUX86Vendor() or
  //! SetCPUX86VendorString() has been used to set the CPU vendor to
  //! “AuthenticAMD”.
  //!
  //! \note Do not call this method if SetCPUArchitecture() has been used to set
  //!     the CPU architecture to #kMinidumpCPUArchitectureAMD64.
  void SetCPUX86AMDExtendedFeatures(uint32_t extended_features);

  //! \brief Sets \ref CPU_INFORMATION::ProcessorFeatures
  //!     "MINIDUMP_SYSTEM_INFO::Cpu::OtherCpuInfo::ProcessorFeatures".
  //!
  //! This is only valid if SetCPUArchitecture() has been used to set the CPU
  //! architecture to an architecture other than #kMinidumpCPUArchitectureX86
  //! or #kMinidumpCPUArchitectureX86Win64.
  //!
  //! \note This method may be called if SetCPUArchitecture() has been used to
  //!     set the CPU architecture to #kMinidumpCPUArchitectureAMD64.
  void SetCPUOtherFeatures(uint64_t features_0, uint64_t features_1);

 protected:
  // MinidumpWritable:
  bool Freeze() override;
  size_t SizeOfObject() override;
  std::vector<MinidumpWritable*> Children() override;
  bool WriteObject(FileWriterInterface* file_writer) override;

  // MinidumpStreamWriter:
  MinidumpStreamType StreamType() const override;

 private:
  MINIDUMP_SYSTEM_INFO system_info_;
  std::unique_ptr<internal::MinidumpUTF16StringWriter> csd_version_;
};

}  // namespace crashpad

#endif  // CRASHPAD_MINIDUMP_MINIDUMP_SYSTEM_INFO_WRITER_H_
