/*
 *  Copyright (c) 2018 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 MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_TEST_FACTORY_H_
#define MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_TEST_FACTORY_H_

#include <memory>
#include <string>

#include "absl/types/optional.h"
#include "modules/audio_coding/neteq/tools/neteq_test.h"
#include "test/field_trial.h"

namespace webrtc {
namespace test {

class SsrcSwitchDetector;
class NetEqStatsGetter;
class NetEqStatsPlotter;

// Note that the NetEqTestFactory needs to be alive when the NetEqTest object is
// used for a simulation.
class NetEqTestFactory {
 public:
  NetEqTestFactory();
  ~NetEqTestFactory();
  struct Config {
    Config();
    Config(const Config& other);
    ~Config();
    // RTP payload type for PCM-u.
    static constexpr int default_pcmu() { return 0; }
    int pcmu = default_pcmu();
    // RTP payload type for PCM-a.
    static constexpr int default_pcma() { return 8; }
    int pcma = default_pcma();
    // RTP payload type for iLBC.
    static constexpr int default_ilbc() { return 102; }
    int ilbc = default_ilbc();
    // RTP payload type for iSAC.
    static constexpr int default_isac() { return 103; }
    int isac = default_isac();
    // RTP payload type for iSAC-swb (32 kHz).
    static constexpr int default_isac_swb() { return 104; }
    int isac_swb = default_isac_swb();
    // RTP payload type for Opus.
    static constexpr int default_opus() { return 111; }
    int opus = default_opus();
    // RTP payload type for PCM16b-nb (8 kHz).
    static constexpr int default_pcm16b() { return 93; }
    int pcm16b = default_pcm16b();
    // RTP payload type for PCM16b-wb (16 kHz).
    static constexpr int default_pcm16b_wb() { return 94; }
    int pcm16b_wb = default_pcm16b_wb();
    // RTP payload type for PCM16b-swb32 (32 kHz).
    static constexpr int default_pcm16b_swb32() { return 95; }
    int pcm16b_swb32 = default_pcm16b_swb32();
    // RTP payload type for PCM16b-swb48 (48 kHz).
    static constexpr int default_pcm16b_swb48() { return 96; }
    int pcm16b_swb48 = default_pcm16b_swb48();
    // RTP payload type for G.722.
    static constexpr int default_g722() { return 9; }
    int g722 = default_g722();
    // RTP payload type for AVT/DTMF (8 kHz).
    static constexpr int default_avt() { return 106; }
    int avt = default_avt();
    // RTP payload type for AVT/DTMF (16 kHz).
    static constexpr int default_avt_16() { return 114; }
    int avt_16 = default_avt_16();
    // RTP payload type for AVT/DTMF (32 kHz).
    static constexpr int default_avt_32() { return 115; }
    int avt_32 = default_avt_32();
    // RTP payload type for AVT/DTMF (48 kHz).
    static constexpr int default_avt_48() { return 116; }
    int avt_48 = default_avt_48();
    // RTP payload type for redundant audio (RED).
    static constexpr int default_red() { return 117; }
    int red = default_red();
    // RTP payload type for comfort noise (8 kHz).
    static constexpr int default_cn_nb() { return 13; }
    int cn_nb = default_cn_nb();
    // RTP payload type for comfort noise (16 kHz).
    static constexpr int default_cn_wb() { return 98; }
    int cn_wb = default_cn_wb();
    // RTP payload type for comfort noise (32 kHz).
    static constexpr int default_cn_swb32() { return 99; }
    int cn_swb32 = default_cn_swb32();
    // RTP payload type for comfort noise (48 kHz).
    static constexpr int default_cn_swb48() { return 100; }
    int cn_swb48 = default_cn_swb48();
    // A PCM file that will be used to populate dummy RTP packets.
    std::string replacement_audio_file;
    // Only use packets with this SSRC.
    absl::optional<uint32_t> ssrc_filter;
    // Extension ID for audio level (RFC 6464).
    static constexpr int default_audio_level() { return 1; }
    int audio_level = default_audio_level();
    // Extension ID for absolute sender time.
    static constexpr int default_abs_send_time() { return 3; }
    int abs_send_time = default_abs_send_time();
    // Extension ID for transport sequence number.
    static constexpr int default_transport_seq_no() { return 5; }
    int transport_seq_no = default_transport_seq_no();
    // Extension ID for video content type.
    static constexpr int default_video_content_type() { return 7; }
    int video_content_type = default_video_content_type();
    // Extension ID for video timing.
    static constexpr int default_video_timing() { return 8; }
    int video_timing = default_video_timing();
    // Generate a matlab script for plotting the delay profile.
    bool matlabplot = false;
    // Generates a python script for plotting the delay profile.
    bool pythonplot = false;
    // Prints concealment events.
    bool concealment_events = false;
    // Maximum allowed number of packets in the buffer.
    static constexpr int default_max_nr_packets_in_buffer() { return 50; }
    int max_nr_packets_in_buffer = default_max_nr_packets_in_buffer();
    // Number of dummy packets to put in the packet buffer at the start of the
    // simulation.
    static constexpr int default_initial_dummy_packets() { return 0; }
    int initial_dummy_packets = default_initial_dummy_packets();
    // Number of getAudio events to skip at the start of the simulation.
    static constexpr int default_skip_get_audio_events() { return 0; }
    int skip_get_audio_events = default_skip_get_audio_events();
    // Enables jitter buffer fast accelerate.
    bool enable_fast_accelerate = false;
    // Dumps events that describes the simulation on a step-by-step basis.
    bool textlog = false;
    // If specified and |textlog| is true, the output of |textlog| is written to
    // the specified file name.
    absl::optional<std::string> textlog_filename;
    // Base name for the output script files for plotting the delay profile.
    absl::optional<std::string> plot_scripts_basename;
    // Path to the output audio file.
    absl::optional<std::string> output_audio_filename;
    // Field trials to use during the simulation.
    std::string field_trial_string;
  };

  std::unique_ptr<NetEqTest> InitializeTestFromFile(
      const std::string& input_filename,
      NetEqFactory* neteq_factory,
      const Config& config);
  std::unique_ptr<NetEqTest> InitializeTestFromString(
      const std::string& input_string,
      NetEqFactory* neteq_factory,
      const Config& config);

 private:
  std::unique_ptr<NetEqTest> InitializeTest(std::unique_ptr<NetEqInput> input,
                                            NetEqFactory* neteq_factory,
                                            const Config& config);
  std::unique_ptr<SsrcSwitchDetector> ssrc_switch_detector_;
  std::unique_ptr<NetEqStatsPlotter> stats_plotter_;
  // The field trials are stored in the test factory, because neteq_test is not
  // in a testonly target, and therefore cannot use ScopedFieldTrials.
  std::unique_ptr<ScopedFieldTrials> field_trials_;
};

}  // namespace test
}  // namespace webrtc

#endif  // MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_TEST_FACTORY_H_
