/*
 * Copyright (c) 2024, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 3-Clause Clear License
 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
 * License was not distributed with this source code in the LICENSE file, you
 * can obtain it at www.aomedia.org/license/software-license/bsd-3-c-c. If the
 * Alliance for Open Media Patent License 1.0 was not distributed with this
 * source code in the PATENTS file, you can obtain it at
 * www.aomedia.org/license/patent.
 */
#ifndef CLI_IAMF_ENCODER_H_
#define CLI_IAMF_ENCODER_H_

#include <cstdint>
#include <list>
#include <memory>
#include <optional>
#include <utility>
#include <vector>

#include "absl/base/nullability.h"
#include "absl/container/flat_hash_map.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "iamf/cli/audio_element_with_data.h"
#include "iamf/cli/audio_frame_decoder.h"
#include "iamf/cli/audio_frame_with_data.h"
#include "iamf/cli/channel_label.h"
#include "iamf/cli/demixing_module.h"
#include "iamf/cli/global_timing_module.h"
#include "iamf/cli/loudness_calculator_factory_base.h"
#include "iamf/cli/parameter_block_with_data.h"
#include "iamf/cli/parameters_manager.h"
#include "iamf/cli/proto/test_vector_metadata.pb.h"
#include "iamf/cli/proto/user_metadata.pb.h"
#include "iamf/cli/proto_conversion/proto_to_obu/audio_frame_generator.h"
#include "iamf/cli/proto_conversion/proto_to_obu/parameter_block_generator.h"
#include "iamf/cli/renderer_factory.h"
#include "iamf/cli/rendering_mix_presentation_finalizer.h"
#include "iamf/obu/arbitrary_obu.h"
#include "iamf/obu/codec_config.h"
#include "iamf/obu/ia_sequence_header.h"
#include "iamf/obu/mix_presentation.h"
#include "iamf/obu/param_definition_variant.h"
#include "iamf/obu/types.h"

namespace iamf_tools {

/*!\brief A class that encodes an IA Sequence and generates OBUs.
 *
 * Descriptor OBUs are generated once at the beginning, and data OBUs are
 * generated iteratively for each temporal unit (TU). The use pattern of this
 * class is:
 *   // Call factory function.
 *   absl::StatusOr<IamfEncoder> encoder = IamfEncoder::Create(...);
 *   if(!encoder.ok()) {
 *     // Handle error.
 *   }
 *
 *   while (encoder->GeneratingDataObus()) {
 *     // Prepare for the next temporal unit; clear state of the previous TU.
 *     encoder->BeginTemporalUnit();
 *
 *     // For all audio elements and labels corresponding to this temporal unit:
 *     for each audio element: {
 *       for each channel label from the current element {
 *         encoder->AddSamples(audio_element_id, label, samples);
 *       }
 *     }
 *
 *     // When all samples (for all temporal units) are added:
 *     if (done_receiving_all_audio) {
 *       encoder->FinalizeAddSamples();
 *     }
 *
 *     // For all parameter block metadata corresponding to this temporal unit:
 *     encoder->AddParameterBlockMetadata(...);
 *
 *     // Get OBUs for next encoded temporal unit.
 *     encoder->OutputTemporalUnit(...);
 *   }
 *   // Get the final mix presentation OBUs, with measured loudness information.
 *   auto mix_presentation_obus = encoder->GetFinalizedMixPresentationObus();
 *
 * Note the timestamps corresponding to `AddSamples()` and
 * `AddParameterBlockMetadata()` might be different from that of the output
 * OBUs obtained in `OutputTemporalUnit()`, because some codecs introduce a
 * frame of delay. We thus distinguish the concepts of input and output
 * timestamps (`input_timestamp` and `output_timestamp`) in the code below.
 */
class IamfEncoder {
 public:
  /*!\brief Factory function to create an `IamfEncoder`.
   *
   * \param user_metadata Input user metadata describing the IAMF stream.
   * \param renderer_factory Factory to create renderers for use in measuring
   *        the loudness.
   * \param loudness_calculator_factory Factory to create loudness calculators
   *        to measure the loudness of the output layouts.
   * \param sample_processor_factory Factory to create processors for use after
   *        rendering.
   * \param ia_sequence_header_obu Generated IA Sequence Header OBU.
   * \param codec_config_obus Map of Codec Config ID to generated Codec Config
   *        OBUs.
   * \param audio_elements Map of Audio Element IDs to generated OBUs with data.
   * \param preliminary_mix_presentation_obus List of preliminary Mix
   *        Presentation OBUs. Using these directly almost certainly results in
   *        incorrect loudness metadata. It is best practice to replace these
   *        with the result of `GetFinalizedMixPresentationObus()` after all
   *        data OBUs are generated.
   * \param arbitrary_obus List of generated Arbitrary OBUs.
   * \return `absl::OkStatus()` if successful. A specific status on failure.
   */
  static absl::StatusOr<IamfEncoder> Create(
      const iamf_tools_cli_proto::UserMetadata& user_metadata,
      absl::Nullable<const RendererFactoryBase*> renderer_factory,
      absl::Nullable<const LoudnessCalculatorFactoryBase*>
          loudness_calculator_factory,
      const RenderingMixPresentationFinalizer::SampleProcessorFactory&
          sample_processor_factory,
      std::optional<IASequenceHeaderObu>& ia_sequence_header_obu,
      absl::flat_hash_map<uint32_t, CodecConfigObu>& codec_config_obus,
      absl::flat_hash_map<DecodedUleb128, AudioElementWithData>& audio_elements,
      std::list<MixPresentationObu>& preliminary_mix_presentation_obus,
      std::list<ArbitraryObu>& arbitrary_obus);

  /*!\brief Returns whether this encoder is generating data OBUs.
   *
   * \return True if still generating data OBUs.
   */
  bool GeneratingDataObus() const;

  /*!\brief Clears the state, e.g. accumulated samples for next temporal unit.
   */
  void BeginTemporalUnit();

  /*!\brief Gets the input timestamp of the data OBU generation iteration.
   *
   * \param input_timestamp Result of input timestamp.
   * \return `absl::OkStatus()` if successful. A specific status on failure.
   */
  absl::Status GetInputTimestamp(int32_t& input_timestamp);

  /*!\brief Adds audio samples belonging to the same temporal unit.
   *
   * The best practice is to not call this function after
   * `FinalizeAddSamples()`. But it is OK if you do -- just that the added
   * samples will be ignored and not encoded.
   *
   * \param audio_element_id ID of the audio element to add samples to.
   * \param label Channel label to add samples to.
   * \param samples Audio samples to add.
   */
  void AddSamples(DecodedUleb128 audio_element_id, ChannelLabel::Label label,
                  const std::vector<InternalSampleType>& samples);

  /*!\brief Finalizes the process of adding samples.
   *
   * This will signal the underlying codecs to flush all remaining samples,
   * as well as trim samples from the end.
   */
  void FinalizeAddSamples();

  /*!\brief Adds parameter block metadata belonging to the same temporal unit.
   *
   * \param parameter_block_metadata Parameter block metadata to add.
   * \return `absl::OkStatus()` if successful. A specific status on failure.
   */
  absl::Status AddParameterBlockMetadata(
      const iamf_tools_cli_proto::ParameterBlockObuMetadata&
          parameter_block_metadata);

  /*!\brief Outputs data OBUs corresponding to one temporal unit.
   *
   * \param audio_frames List of generated audio frames corresponding to this
   *        temporal unit.
   * \param parameter_blocks List of generated parameter block corresponding
   *        to this temporal unit.
   * \return `absl::OkStatus()` if successful. A specific status on failure.
   */
  absl::Status OutputTemporalUnit(
      std::list<AudioFrameWithData>& audio_frames,
      std::list<ParameterBlockWithData>& parameter_blocks);

  /*!\brief Gets the finalized mix presentation OBUs.
   *
   * Mix Presentation OBUs contain loudness information, which is only possible
   * to know after all data OBUs are generated.
   *
   * Must only be called only once and after all data OBUs are generated, i.e.
   * after `GeneratingDataObus()` returns false.
   *
   * \return Finalized Mix Presentation OBUs. A specific status on failure.
   */
  absl::StatusOr<std::list<MixPresentationObu>>
  GetFinalizedMixPresentationObus();

 private:
  /*!\brief Private constructor.
   *
   * Moves from the input arguments Some arguments are wrapped in unique
   * pointers to ensure pointer or reference stability after move.
   *
   * \param validate_user_loudness Whether to validate the user-provided
   *        loudness.
   * \param parameter_id_to_metadata Mapping from parameter IDs to per-ID
   *        parameter metadata.
   * \param param_definition_variants Parameter definitions for the IA Sequence.
   * \param parameters_manager Manager to support internal querying
   *        of parameters.
   * \param demixing_module Module to demix audio elements.
   * \param audio_frame_generator Audio frame generator.
   * \param audio_frame_decoder Decodes the original audio frames, to facilitate
   *        recon gain computation.
   * \param global_timing_module Manages global timing information.
   */
  IamfEncoder(bool validate_user_loudness,
              std::unique_ptr<
                  absl::flat_hash_map<DecodedUleb128, ParamDefinitionVariant>>
                  param_definition_variants,
              ParameterBlockGenerator&& parameter_block_generator,
              std::unique_ptr<ParametersManager> parameters_manager,
              const DemixingModule& demixing_module,
              std::unique_ptr<AudioFrameGenerator> audio_frame_generator,
              AudioFrameDecoder&& audio_frame_decoder,
              std::unique_ptr<GlobalTimingModule> global_timing_module,
              RenderingMixPresentationFinalizer&& mix_presentation_finalizer)
      : validate_user_loudness_(validate_user_loudness),
        param_definition_variants_(std::move(param_definition_variants)),
        parameter_block_generator_(std::move(parameter_block_generator)),
        parameters_manager_(std::move(parameters_manager)),
        demixing_module_(demixing_module),
        audio_frame_generator_(std::move(audio_frame_generator)),
        audio_frame_decoder_(std::move(audio_frame_decoder)),
        global_timing_module_(std::move(global_timing_module)),
        mix_presentation_finalizer_(std::move(mix_presentation_finalizer)) {}

  const bool validate_user_loudness_;

  // Mapping from parameter IDs to parameter definitions.
  // Parameter block generator owns a reference to this map. Wrapped in
  // `std::unique_ptr` for reference stability after move.
  absl::Nonnull<std::unique_ptr<
      const absl::flat_hash_map<DecodedUleb128, ParamDefinitionVariant>>>
      param_definition_variants_;

  // Saved parameter blocks generated in one iteration.
  std::list<ParameterBlockWithData> temp_mix_gain_parameter_blocks_;
  std::list<ParameterBlockWithData> temp_demixing_parameter_blocks_;
  std::list<ParameterBlockWithData> temp_recon_gain_parameter_blocks_;

  // Cached mapping from Audio Element ID to labeled samples added in the same
  // iteration.
  absl::flat_hash_map<DecodedUleb128, LabelSamplesMap> id_to_labeled_samples_;

  // Whether the `FinalizeAddSamples()` has been called.
  bool add_samples_finalized_ = false;

  // Various generators and modules used when generating data OBUs iteratively.
  // Some are held in `unique_ptr` for reference stability after move.
  ParameterBlockGenerator parameter_block_generator_;
  absl::Nonnull<std::unique_ptr<ParametersManager>> parameters_manager_;
  const DemixingModule demixing_module_;
  absl::Nonnull<std::unique_ptr<AudioFrameGenerator>> audio_frame_generator_;
  AudioFrameDecoder audio_frame_decoder_;
  absl::Nonnull<std::unique_ptr<GlobalTimingModule>> global_timing_module_;

  // Modules to render the output layouts and measure their loudness.
  RenderingMixPresentationFinalizer mix_presentation_finalizer_;
};

}  // namespace iamf_tools

#endif  // CLI_IAMF_ENCODER_H_
