/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree.
 */

#pragma once

#include <cinttypes>
#include <cstdint>

#include <executorch/runtime/core/data_loader.h>
#include <executorch/runtime/core/error.h>
#include <executorch/runtime/core/event_tracer.h>
#include <executorch/runtime/core/freeable_buffer.h>
#include <executorch/runtime/core/result.h>
#include <executorch/runtime/executor/memory_manager.h>
#include <executorch/runtime/executor/method.h>
#include <executorch/runtime/executor/method_meta.h>
#include <executorch/runtime/platform/compiler.h>

// Forward declare flatbuffer types. This is a public header and must not
// include the generated flatbuffer header.
namespace executorch_flatbuffer {
struct Program;
} // namespace executorch_flatbuffer

namespace executorch {
namespace runtime {

namespace testing {
// Provides test access to private Program methods.
class ProgramTestFriend;
} // namespace testing

namespace deserialization {
// Provides Tensor deserializaiton access to private Program methods.
class TensorParser;
} // namespace deserialization

/**
 * A deserialized ExecuTorch program binary.
 */
class Program final {
 public:
  /**
   * Types of validation that the Program can do before parsing the data.
   */
  enum class Verification : uint8_t {
    /**
     * Do minimal verification of the data, ensuring that the header appears
     * correct.
     *
     * Has minimal runtime overhead.
     */
    Minimal,
    /**
     * Do full verification of the data, ensuring that internal pointers are
     * self-consistent and that the data has not been truncated or obviously
     * corrupted. May not catch all types of corruption, but should guard
     * against illegal memory operations during parsing.
     *
     * Will have higher runtime overhead, scaling with the complexity of the
     * proram data.
     */
    InternalConsistency,
  };

  /**
   * Loads a Program from the provided loader. The Program will hold a pointer
   * to the loader, which must outlive the returned Program instance.
   *
   * @param[in] loader The source to load program data from. The Program will
   *     hold a pointer to this loader, which must outlive the returned Program
   *     instance.
   * @param[in] verification The type of verification to do before returning
   *     success.
   */
  ET_NODISCARD static Result<Program> load(
      DataLoader* loader,
      Verification verification = Verification::Minimal);

  /// DEPRECATED: Use the lowercase `load()` instead.
  ET_DEPRECATED ET_NODISCARD static Result<Program> Load(
      DataLoader* loader,
      Verification verification = Verification::Minimal) {
    return load(loader, verification);
  }

  // Movable, to be compatible with Result.
  Program(Program&&) noexcept = default;
  ~Program() = default;

  /**
   * Get the constant buffer inside Program with index buffer_idx.
   * @param[in] buffer_idx the index of the buffer in the constant_buffer.
   * @param[in] nbytes the number of bytes to read from the buffer.
   * @return The buffer with corresponding index.
   */
  Result<const void*> get_constant_buffer_data(size_t buffer_idx, size_t nbytes)
      const;

  /**
   * Returns the number of methods in the program.
   */
  size_t num_methods() const;

  /**
   * Returns the name of the method at particular index.
   *
   * @param[in] method_index The index of the method name to retrieve. Must be
   * less than the value returned by `num_methods()`.
   *
   * @returns The name of the requested method. The pointer is owned by the
   * Program, and has the same lifetime as the Program.
   */
  Result<const char*> get_method_name(size_t method_index) const;

  /**
   * Loads the named method and prepares it for execution.
   *
   * @param[in] method_name The name of the method to load.
   * @param[in] memory_manager The allocators to use during initialization and
   *     execution of the loaded method.
   * @param[in] event_tracer The event tracer to use for this method run.
   *
   * @returns The loaded method on success, or an error on failure.
   */
  Result<Method> load_method(
      const char* method_name,
      MemoryManager* memory_manager,
      EventTracer* event_tracer = nullptr) const;

  /**
   * Gathers metadata for the named method.
   *
   * @param[in] method_name The name of the method to get metadata for.
   */
  Result<MethodMeta> method_meta(const char* method_name) const;

  /**
   * DEPRECATED: Get the pytree encoding string for the output. Deprecated as
   * this functionality will eventually move out of the core program into a
   * higher level structure, but that does not exist at this time.
   * @param[in] method_name The name of the method to get the encoding for.
   *
   * @return The pytree encoding string for the output
   */
  ET_DEPRECATED Result<const char*> get_output_flattening_encoding(
      const char* method_name = "forward") const;

  /**
   * Describes the presence of an ExecuTorch program header.
   */
  enum HeaderStatus {
    /**
     * An ExecuTorch program header is present, and its version is compatible
     * with this version of the runtime.
     */
    CompatibleVersion,

    /**
     * An ExecuTorch program header is present, but its version is not
     * compatible with this version of the runtime.
     */
    IncompatibleVersion,

    /**
     * An ExecuTorch program header is not present.
     */
    NotPresent,

    /**
     * The data provided was too short to find the program header.
     */
    ShortData,
  };

  /**
   * The minimum number of bytes necessary for calls to `check_header`.
   */
  static constexpr size_t kMinHeadBytes = 64;

  /**
   * Looks for an ExecuTorch program header in the provided data.
   *
   * @param[in] data The data from the beginning of a file that might contain
   *     an ExecuTorch program.
   * @param[in] size The size of `data` in bytes. Must be >= `kMinHeadBytes`.
   *
   * @returns A value describing the presence of a header in the data.
   */
  static HeaderStatus check_header(const void* data, size_t size);

 private:
  // Let some classes call these private methods.
  friend class BackendDelegate;
  friend class Executor;
  friend class Method;
  friend class deserialization::TensorParser;
  friend class testing::ProgramTestFriend;

  const executorch_flatbuffer::Program* get_internal_program() const {
    return internal_program_;
  }

  // Used by Method to look up entries in the delegate data table.
  Error get_backend_delegate_data(
      size_t index,
      const void** out_data,
      size_t* out_size) const;

  /**
   * Loads a segment by index.
   *
   * @param[in] segment_info Struct containing an index to load from the
   * Program.segments list. The other fields of the struct, such as
   * `segment_type` and `descriptor`, need to also be correct.
   *
   * @returns The data as a FreeableBuffer, if the index is valid.
   * @retval Error::NotFound The program does not contain any segments or the
   *     index is out of range.
   * @returns Other errors depending on the implementation of
   *     DataLoader: The Program.segment table is inconsistent, or the
   *     data cannot be accessed.
   */
  ET_NODISCARD Result<FreeableBuffer> LoadSegment(
      const DataLoader::SegmentInfo& segment_info) const;

  /**
   * Loads a portion of a mutable segment into the provided buffer.
   *
   * @param[in] mutable_data_segments_index The index into the
   * mutable_data_segments_array.
   * @param[in] offset_index The index into the segment's offsets array.
   * @param[in] size The number of bytes to load.
   * @param[in] buffer The buffer to load data into. Must point to at least
   * `size` bytes of memory.
   *
   * @returns An error code on if the load was successful.
   * @retval Error::Ok The load was successful.
   * @retval Error::NotFound The program does not contain any segments or the
   *     indices are out of range.
   * @returns Other errors depending on the implementation of
   *     DataLoader: The Program.segment table is inconsistent, or the
   *     data cannot be accessed.
   */
  ET_NODISCARD Error load_mutable_subsegment_into(
      size_t mutable_data_segments_index,
      size_t offset_index,
      size_t size,
      void* buffer) const;

 private:
  Program(
      DataLoader* loader,
      size_t segment_base_offset,
      FreeableBuffer&& program_data,
      const executorch_flatbuffer::Program* internal_program,
      FreeableBuffer&& constant_segment_data)
      : program_data_(std::move(program_data)),
        // Don't need the loader if there are no segments.
        loader_(segment_base_offset > 0 ? loader : nullptr),
        internal_program_(internal_program),
        segment_base_offset_(segment_base_offset),
        constant_segment_data_(std::move(constant_segment_data)) {}

  // Not copyable or assignable.
  Program(const Program& rhs) = delete;
  Program& operator=(Program&& rhs) noexcept = delete;
  Program& operator=(const Program& rhs) = delete;

  /// The serialized program data. Tensors will point directly into this buffer.
  FreeableBuffer program_data_;

  /// Used to load segment data. Null if there are no segments.
  DataLoader* loader_;

  /// The flatbuffer representation of the program. Must not be exposed to
  /// users.
  const executorch_flatbuffer::Program* internal_program_;

  /// The offset to the first segment, in bytes. If zero, no segments should
  /// be present in internal_program_.
  size_t segment_base_offset_;

  /// Constant segment data.
  FreeableBuffer constant_segment_data_;
};

} // namespace runtime
} // namespace executorch

namespace torch {
namespace executor {
// TODO(T197294990): Remove these deprecated aliases once all users have moved
// to the new `::executorch` namespaces.
using ::executorch::runtime::Program;
} // namespace executor
} // namespace torch
