/*
 *  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"

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;
    // Generates a text log describing the simulation on a step-by-step basis.
    bool textlog = 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();
    // Enables jitter buffer fast accelerate.
    bool enable_fast_accelerate = false;
  };

  std::unique_ptr<NetEqTest> InitializeTest(std::string input_filename,
                                            std::string output_filename,
                                            const Config& config);

 private:
  std::unique_ptr<SsrcSwitchDetector> ssrc_switch_detector_;
  std::unique_ptr<NetEqStatsPlotter> stats_plotter_;
};

}  // namespace test
}  // namespace webrtc

#endif  // MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_TEST_FACTORY_H_
