// Copyright 2018 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_SNAPSHOT_FUCHSIA_PROCESS_READER_H_
#define CRASHPAD_SNAPSHOT_FUCHSIA_PROCESS_READER_H_

#include <lib/zx/process.h>
#include <zircon/syscalls/debug.h>

#include <memory>
#include <vector>

#include "build/build_config.h"
#include "snapshot/elf/elf_image_reader.h"
#include "snapshot/fuchsia/memory_map_fuchsia.h"
#include "snapshot/module_snapshot.h"
#include "util/misc/initialization_state_dcheck.h"
#include "util/numeric/checked_range.h"
#include "util/process/process_memory_fuchsia.h"
#include "util/process/process_memory_range.h"

namespace crashpad {

//! \brief Accesses information about another process, identified by a Fuchsia
//!     process.
class ProcessReaderFuchsia {
 public:
  //! \brief Contains information about a module loaded into a process.
  struct Module {
    Module();
    ~Module();

    //! \brief The `ZX_PROP_NAME` of the module.
    std::string name;

    //! \brief An image reader for the module.
    //!
    //! The lifetime of this ElfImageReader is scoped to the lifetime of the
    //! ProcessReaderFuchsia that created it.
    //!
    //! This field may be `nullptr` if a reader could not be created for the
    //! module.
    ElfImageReader* reader;

    //! \brief The module's type.
    ModuleSnapshot::ModuleType type = ModuleSnapshot::kModuleTypeUnknown;
  };

  //! \brief Contains information about a thread that belongs to a process.
  struct Thread {
    Thread();
    ~Thread();

    //! \brief The kernel identifier for the thread.
    zx_koid_t id = ZX_KOID_INVALID;

    //! \brief The state of the thread, the `ZX_THREAD_STATE_*` value or `-1` if
    //!     the value could not be retrieved.
    uint32_t state = -1;

    //! \brief The `ZX_PROP_NAME` property of the thread. This may be empty.
    std::string name;

    //! \brief The raw architecture-specific `zx_thread_state_general_regs_t` as
    //!     returned by `zx_thread_read_state()`.
    zx_thread_state_general_regs_t general_registers = {};

    //! \brief The raw architecture-specific `zx_thread_state_fp_regs_t` as
    //!     returned by `zx_thread_read_state()`.
    zx_thread_state_fp_regs_t fp_registers = {};

    //! \brief The raw architecture-specific `zx_thread_state_vector_regs_t` as
    //!     returned by `zx_thread_read_state()`.
    zx_thread_state_vector_regs_t vector_registers = {};

    //! \brief The regions representing the stack. The first entry in the vector
    //!     represents the callstack, and further entries optionally identify
    //!     other stack data when the thread uses a split stack representation.
    std::vector<CheckedRange<zx_vaddr_t, size_t>> stack_regions;
  };

  ProcessReaderFuchsia();

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

  ~ProcessReaderFuchsia();

  //! \brief Initializes this object. This method must be called before any
  //!     other.
  //!
  //! \param[in] process A process handle with permissions to read properties
  //!     and memory from the target process.
  //!
  //! \return `true` on success, indicating that this object will respond
  //!     validly to further method calls. `false` on failure. On failure, no
  //!     further method calls should be made.
  bool Initialize(const zx::process& process);

  //! \return The modules loaded in the process. The first element (at index
  //!     `0`) corresponds to the main executable.
  const std::vector<Module>& Modules();

  //! \return The threads that are in the process.
  const std::vector<Thread>& Threads();

  //! \brief Return a memory reader for the target process.
  const ProcessMemory* Memory() const { return process_memory_.get(); }

  //! \brief Return a memory map for the target process.
  const MemoryMapFuchsia* MemoryMap();

 private:
  //! Performs lazy initialization of the \a modules_ vector on behalf of
  //! Modules().
  void InitializeModules();

  //! Performs lazy initialization of the \a threads_ vector on behalf of
  //! Threads().
  void InitializeThreads();

  //! Performs lazy initialization of the \a memory_map_ on behalf of
  //! MemoryMap().
  void InitializeMemoryMap();

  std::vector<Module> modules_;
  std::vector<Thread> threads_;
  std::vector<std::unique_ptr<ElfImageReader>> module_readers_;
  std::vector<std::unique_ptr<ProcessMemoryRange>> process_memory_ranges_;
  std::unique_ptr<ProcessMemoryFuchsia> process_memory_;
  std::unique_ptr<MemoryMapFuchsia> memory_map_;
  zx::unowned_process process_;
  bool initialized_modules_ = false;
  bool initialized_threads_ = false;
  bool initialized_memory_map_ = false;
  InitializationStateDcheck initialized_;
};

}  // namespace crashpad

#endif  // CRASHPAD_SNAPSHOT_FUCHSIA_PROCESS_READER_H_
