#ifndef __MAIN_H__
#define __MAIN_H__

#include "RkAudio.h"
#include <fstream>
#include <memory>
#include "WavWriter.h"

class SpeexDsp;
class WebRtcAecm;

enum Dsp {
    Vqe,
    Speex,
    AecMobile,
    Aec3,
};

#ifdef __RV1109__
constexpr auto DumpPath = "/sdcard/data";
#else
constexpr auto DumpPath = "./build/data";
#endif

class Task {
public:
    virtual void run() = 0;
    virtual ~Task() {
    }
};

class RecorderTask : public Task {
public:
    void run() final;

private:
    std::shared_ptr<RkAudio::Input> m_input;
    std::shared_ptr<std::ofstream> m_ofs;
};

class PlayerTask : public Task {
public:
    void setChannels(int channels);
    void setPath(const std::string &path);
    void run() final;

protected:
    void play();

private:
    int m_channels = 2;
    std::string m_path;
    std::vector<char> m_buffer;
    std::shared_ptr<std::ifstream> m_ifs;
    std::shared_ptr<RkAudio::Output> m_output;
};

class EchoRecordPrivate;
class EchoRecordTask : public Task {
public:
    EchoRecordTask();
    ~EchoRecordTask();
    void setDsp(Dsp dsp);
    void setDumpEnabled(bool enabled);
    void setChannels(int channels);
    void run() final;

private:
    int m_channels = 2;
    Dsp m_dsp = Vqe;
    std::shared_ptr<RkAudio::Output> m_output;
    std::shared_ptr<RkAudio::Input> m_input;
    std::shared_ptr<SpeexDsp> m_speex;
    std::shared_ptr<WebRtcAecm> m_webRtcAecm;
    std::vector<uint8_t> m_outBuffer;

    std::vector<uint8_t> m_nearendBuffer;
    std::vector<uint8_t> m_farendBuffer;

    EchoRecordPrivate *m_d = nullptr;
    std::shared_ptr<std::ofstream> m_outOfs;
    std::shared_ptr<std::ofstream> m_micOfs;
};

class ProcessFileTaskPrivate;
class ProcessFileTask : public Task {
public:
    ProcessFileTask();
    ~ProcessFileTask();
    void setDsp(Dsp dsp);
    void run() final;

protected:
    void process();

private:
    ProcessFileTaskPrivate *m_d = nullptr;
    Dsp m_dsp = Speex;
    std::shared_ptr<SpeexDsp> m_speex;
    std::shared_ptr<WebRtcAecm> m_webRtcAecm;
    std::shared_ptr<std::ifstream> m_speakerIfs;
    std::shared_ptr<std::ifstream> m_micIfs;
    std::shared_ptr<WavWriter<int16_t>> m_ofs;
    std::shared_ptr<std::ofstream> m_nsOfs; // 降噪后的文件
    std::string m_outFilename;
    std::chrono::system_clock::time_point m_begin;
};

Dsp dspFromString(const std::string &dsp);
std::string dspToString(Dsp dsp);

#endif // __MAIN_H__