#pragma once

#include <iostream>
#include <fstream>

#include "idevice_data_observer.h"
#include "mini_audio.h"


namespace DUBBING
{

    class DeviceTransformDataObserver : public IDeviceDataObserver
    {
    public:
        DeviceTransformDataObserver()
        {

        }

        ~DeviceTransformDataObserver()
        {

        }

        void onCaptureDataEvent(ma_device* pDevice, std::shared_ptr<AudioFrameData> audioFramePtr) override
        {
            if (audioFramePtr)
            {
                //std::ofstream file(L"d:/onCaptureDataEvent.pcm", std::ios::binary | std::ios::app);
                //file.write(audioFramePtr->m_data, audioFramePtr->m_dataLen);
                //file.close();

                saveRecordCalibrationFile(audioFramePtr);

                if (m_engine)
                {
                    m_engine->transform(audioFramePtr->m_data, audioFramePtr->m_dataLen);
                }
                m_captureFrameQueue.pushAudioFrame(audioFramePtr);
            }
        }

        void onPlaybackDataEvent(ma_device* pDevice, std::shared_ptr<AudioFrameData>& audioFramePtr) override
        {
            audioFramePtr = m_captureFrameQueue.popAudioFrame();
            //if (audioFramePtr)
            //{
            //    std::ofstream file(L"d:/onPlaybackDataEvent.pcm", std::ios::binary | std::ios::app);
            //    file.write(audioFramePtr->m_data, audioFramePtr->m_dataLen);
            //    file.close();
            //}
        }

        void setIDubbingEngine(DUBBING::IDubbingEngine* engine)
        {
            m_engine = engine;
        }

        void startRecordCalibrationFile()
        {
            m_isStartRecord = true;
            std::wstring filePath;
            if (m_engine)
            {
                filePath = utf8string2wstring(m_engine->getCalibrationFile());
            }
            if (!filePath.empty() && std::filesystem::exists(filePath))
            {
                std::filesystem::remove(filePath);
            }
            if (m_file.is_open())
            {
                m_file.close();
            }
            m_file.open(filePath, std::ios::binary);
        }

        void stopRecordCalibrationFile()
        {
            m_isStartRecord = false;
        }

        void saveRecordCalibrationFile(std::shared_ptr<AudioFrameData> audioFramePtr)
        {
            if (m_isStartRecord && audioFramePtr)
            {
                m_file.write(audioFramePtr->m_data, audioFramePtr->m_dataLen);
            }
        }


    private:
        DUBBING::IDubbingEngine* m_engine = nullptr;
        AudioFrameQueue m_captureFrameQueue;
        bool m_isStartRecord = false;
        std::ofstream m_file;
    };

}

