// 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_MISC_INFO_WRITER_H_
#define CRASHPAD_MINIDUMP_MINIDUMP_MISC_INFO_WRITER_H_

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

#include <string>

#include "build/build_config.h"
#include "minidump/minidump_stream_writer.h"
#include "minidump/minidump_writable.h"

namespace crashpad {

class ProcessSnapshot;

namespace internal {

//! \brief Returns the string to set in MINIDUMP_MISC_INFO_4::DbgBldStr.
//!
//! dbghelp produces strings like `"dbghelp.i386,6.3.9600.16520"` and
//! `"dbghelp.amd64,6.3.9600.16520"`. This function mimics that format, and adds
//! the OS that wrote the minidump along with any relevant platform-specific
//! data describing the compilation environment.
//!
//! This function is an implementation detail of
//! MinidumpMiscInfoWriter::InitializeFromSnapshot() and is only exposed for
//! testing purposes.
std::string MinidumpMiscInfoDebugBuildString();

}  // namespace internal

//! \brief The writer for a stream in the MINIDUMP_MISC_INFO family in a
//!     minidump file.
//!
//! The actual stream written will be a MINIDUMP_MISC_INFO,
//! MINIDUMP_MISC_INFO_2, MINIDUMP_MISC_INFO_3, MINIDUMP_MISC_INFO_4, or
//! MINIDUMP_MISC_INFO_5 stream. Later versions of MINIDUMP_MISC_INFO are
//! supersets of earlier versions. The earliest version that supports all of the
//! information that an object of this class contains will be used.
class MinidumpMiscInfoWriter final : public internal::MinidumpStreamWriter {
 public:
  MinidumpMiscInfoWriter();

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

  ~MinidumpMiscInfoWriter() override;

  //! \brief Initializes MINIDUMP_MISC_INFO_N based on \a process_snapshot.
  //!
  //! \param[in] process_snapshot The process 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 ProcessSnapshot* process_snapshot);

  //! \brief Sets the field referenced by #MINIDUMP_MISC1_PROCESS_ID.
  void SetProcessID(uint32_t process_id);

  //! \brief Sets the fields referenced by #MINIDUMP_MISC1_PROCESS_TIMES.
  void SetProcessTimes(time_t process_create_time,
                       uint32_t process_user_time,
                       uint32_t process_kernel_time);

  //! \brief Sets the fields referenced by #MINIDUMP_MISC1_PROCESSOR_POWER_INFO.
  void SetProcessorPowerInfo(uint32_t processor_max_mhz,
                             uint32_t processor_current_mhz,
                             uint32_t processor_mhz_limit,
                             uint32_t processor_max_idle_state,
                             uint32_t processor_current_idle_state);

  //! \brief Sets the field referenced by #MINIDUMP_MISC3_PROCESS_INTEGRITY.
  void SetProcessIntegrityLevel(uint32_t process_integrity_level);

  //! \brief Sets the field referenced by #MINIDUMP_MISC3_PROCESS_EXECUTE_FLAGS.
  void SetProcessExecuteFlags(uint32_t process_execute_flags);

  //! \brief Sets the field referenced by #MINIDUMP_MISC3_PROTECTED_PROCESS.
  void SetProtectedProcess(uint32_t protected_process);

  //! \brief Sets the fields referenced by #MINIDUMP_MISC3_TIMEZONE.
  void SetTimeZone(uint32_t time_zone_id,
                   int32_t bias,
                   const std::string& standard_name,
                   const SYSTEMTIME& standard_date,
                   int32_t standard_bias,
                   const std::string& daylight_name,
                   const SYSTEMTIME& daylight_date,
                   int32_t daylight_bias);

  //! \brief Sets the fields referenced by #MINIDUMP_MISC4_BUILDSTRING.
  void SetBuildString(const std::string& build_string,
                      const std::string& debug_build_string);

  // TODO(mark): Provide a better interface than this. Don’t force callers to
  // build their own XSTATE_CONFIG_FEATURE_MSC_INFO structure.
  //
  //! \brief Sets MINIDUMP_MISC_INFO_5::XStateData.
  void SetXStateData(const XSTATE_CONFIG_FEATURE_MSC_INFO& xstate_data);

  //! \brief Will this write extended context information?
  bool HasXStateData() const;

  //! \brief Sets the field referenced by #MINIDUMP_MISC5_PROCESS_COOKIE.
  void SetProcessCookie(uint32_t process_cookie);

 protected:
  // MinidumpWritable:
  bool Freeze() override;
  size_t SizeOfObject() override;
  bool WriteObject(FileWriterInterface* file_writer) override;
  MinidumpStreamType StreamType() const override;

 private:
  //! \brief Returns the size of the object to be written based on
  //!     MINIDUMP_MISC_INFO_N::Flags1.
  //!
  //! The smallest defined structure type in the MINIDUMP_MISC_INFO family that
  //! can hold all of the data that has been populated will be used.
  size_t CalculateSizeOfObjectFromFlags() const;

  MINIDUMP_MISC_INFO_N misc_info_;
  bool has_xstate_data_;
};

//! \brief Conversion functions from a native UTF16 C-string to a char16_t
//!     C-string. No-op where the native UTF16 string is std::u16string.
#if defined(WCHAR_T_IS_16_BIT) || DOXYGEN
inline const char16_t* AsU16CStr(const wchar_t* str) {
  return reinterpret_cast<const char16_t*>(str);
}

inline char16_t* AsU16CStr(wchar_t* str) {
  return reinterpret_cast<char16_t*>(str);
}
#else
inline const char16_t* AsU16CStr(const char16_t* str) {
  return str;
}

inline char16_t* AsU16CStr(char16_t* str) {
  return str;
}
#endif

}  // namespace crashpad

#endif  // CRASHPAD_MINIDUMP_MINIDUMP_MISC_INFO_WRITER_H_
