/*
 *  Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef API_NETEQ_NETEQ_CONTROLLER_H_
#define API_NETEQ_NETEQ_CONTROLLER_H_

#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>

#include "absl/types/optional.h"
#include "api/neteq/neteq.h"
#include "api/neteq/tick_timer.h"
#include "system_wrappers/include/clock.h"

namespace webrtc {

// Decides the actions that NetEq should take. This affects the behavior of the
// jitter buffer, and how it reacts to network conditions.
// This class will undergo substantial refactoring in the near future, and the
// API is expected to undergo significant changes. A target API is given below:
//
// class NetEqController {
//  public:
//   // Resets object to a clean state.
//   void Reset();
//   // Given NetEq status, make a decision.
//   Operation GetDecision(NetEqStatus neteq_status);
//   // Register every packet received.
//   void RegisterPacket(PacketInfo packet_info);
//   // Register empty packet.
//   void RegisterEmptyPacket();
//   // Register a codec switching.
//   void CodecSwithed();
//   // Sets the sample rate.
//   void SetSampleRate(int fs_hz);
//   // Sets the packet length in samples.
//   void SetPacketLengthSamples();
//   // Sets maximum delay.
//   void SetMaximumDelay(int delay_ms);
//   // Sets mininum delay.
//   void SetMinimumDelay(int delay_ms);
//   // Sets base mininum delay.
//   void SetBaseMinimumDelay(int delay_ms);
//   // Gets target buffer level.
//   int GetTargetBufferLevelMs() const;
//   // Gets filtered buffer level.
//   int GetFilteredBufferLevel() const;
//   // Gets base minimum delay.
//   int GetBaseMinimumDelay() const;
// }

class NetEqController {
 public:
  // This struct is used to create a NetEqController.
  struct Config {
    bool allow_time_stretching;
    bool enable_rtx_handling;
    int max_packets_in_buffer;
    int base_min_delay_ms;
    TickTimer* tick_timer;
    webrtc::Clock* clock = nullptr;
  };

  struct PacketInfo {
    uint32_t timestamp;
    bool is_dtx;
    bool is_cng;
  };

  struct PacketBufferInfo {
    bool dtx_or_cng;
    size_t num_samples;
    size_t span_samples;
    size_t span_samples_wait_time;
    size_t num_packets;
  };

  struct NetEqStatus {
    uint32_t target_timestamp;
    int16_t expand_mutefactor;
    size_t last_packet_samples;
    absl::optional<PacketInfo> next_packet;
    NetEq::Mode last_mode;
    bool play_dtmf;
    size_t generated_noise_samples;
    PacketBufferInfo packet_buffer_info;
    size_t sync_buffer_samples;
  };

  struct PacketArrivedInfo {
    size_t packet_length_samples;
    uint32_t main_timestamp;
    uint16_t main_sequence_number;
    bool is_cng_or_dtmf;
    bool is_dtx;
    bool buffer_flush;
  };

  virtual ~NetEqController() = default;

  // Resets object to a clean state.
  virtual void Reset() = 0;

  // Resets parts of the state. Typically done when switching codecs.
  virtual void SoftReset() = 0;

  // Given info about the latest received packet, and current jitter buffer
  // status, returns the operation. `target_timestamp` and `expand_mutefactor`
  // are provided for reference. `last_packet_samples` is the number of samples
  // obtained from the last decoded frame. If there is a packet available, it
  // should be supplied in `packet`. The mode resulting from the last call to
  // NetEqImpl::GetAudio is supplied in `last_mode`. If there is a DTMF event to
  // play, `play_dtmf` should be set to true. The output variable
  // `reset_decoder` will be set to true if a reset is required; otherwise it is
  // left unchanged (i.e., it can remain true if it was true before the call).
  virtual NetEq::Operation GetDecision(const NetEqStatus& status,
                                       bool* reset_decoder) = 0;

  // Inform NetEqController that an empty packet has arrived.
  virtual void RegisterEmptyPacket() = 0;

  // Sets the sample rate and the output block size.
  virtual void SetSampleRate(int fs_hz, size_t output_size_samples) = 0;

  // Sets a minimum or maximum delay in millisecond.
  // Returns true if the delay bound is successfully applied, otherwise false.
  virtual bool SetMaximumDelay(int delay_ms) = 0;
  virtual bool SetMinimumDelay(int delay_ms) = 0;

  // Sets a base minimum delay in milliseconds for packet buffer. The effective
  // minimum delay can't be lower than base minimum delay, even if a lower value
  // is set using SetMinimumDelay.
  // Returns true if the base minimum is successfully applied, otherwise false.
  virtual bool SetBaseMinimumDelay(int delay_ms) = 0;
  virtual int GetBaseMinimumDelay() const = 0;

  // Reports back to DecisionLogic whether the decision to do expand remains or
  // not. Note that this is necessary, since an expand decision can be changed
  // to kNormal in NetEqImpl::GetDecision if there is still enough data in the
  // sync buffer.
  virtual void ExpandDecision(NetEq::Operation operation) = 0;

  // Adds `value` to `sample_memory_`.
  virtual void AddSampleMemory(int32_t value) = 0;

  // Returns the target buffer level in ms.
  virtual int TargetLevelMs() const = 0;

  // Returns the target buffer level in ms as it would be if no minimum or
  // maximum delay was set.
  // TODO(bugs.webrtc.org/14270): Make pure virtual once all implementations are
  // updated.
  virtual int UnlimitedTargetLevelMs() const { return 0; }

  // Notify the NetEqController that a packet has arrived. Returns the relative
  // arrival delay, if it can be computed.
  virtual absl::optional<int> PacketArrived(int fs_hz,
                                            bool should_update_stats,
                                            const PacketArrivedInfo& info) = 0;

  // Notify the NetEqController that we are currently in muted state.
  // TODO(bugs.webrtc.org/14270): Make pure virtual when downstream is updated.
  virtual void NotifyMutedState() {}

  // Returns true if a peak was found.
  virtual bool PeakFound() const = 0;

  // Get the filtered buffer level in samples.
  virtual int GetFilteredBufferLevel() const = 0;

  // Accessors and mutators.
  virtual void set_sample_memory(int32_t value) = 0;
  virtual size_t noise_fast_forward() const = 0;
  virtual size_t packet_length_samples() const = 0;
  virtual void set_packet_length_samples(size_t value) = 0;
  virtual void set_prev_time_scale(bool value) = 0;
};

}  // namespace webrtc
#endif  // API_NETEQ_NETEQ_CONTROLLER_H_
