package com.baidu.ai.sample.util;

import android.content.Context;
import android.util.Log;

import com.baidu.rtc.agent.AIAgentEngine;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.concurrent.TimeUnit;

public class AudioDevice {
    private static final String TAG = "AudioDevice";
    private static final int SAMPLE_RATE = 16000;
    private FileInputStream fileInputStream;
    private FileOutputStream fileOutputStream;

    private Thread mInputThread;

    private boolean isInputAlive = false;
    private boolean isOutputAlive = false;

    private Context mContext;

    private AIAgentEngine mEngine;

    public AudioDevice(Context context, AIAgentEngine engine) {
        mContext = context;
        mEngine = engine;
    }

    public synchronized void startInput() {
        if (mInputThread != null) {
            return;
        }

        isInputAlive = true;
        mInputThread = new Thread(new Runnable() {
            @Override
            public void run() {
                pushAudioFrame();
            }
        });
        mInputThread.start();
        Log.i(TAG, "startInput");
    }

    public synchronized void startOutput() {
        isOutputAlive = true;
        Log.i(TAG, "startOutput");
    }

    public void destroy() {
        Log.i(TAG, "destroy");
        isInputAlive = false;
        isOutputAlive = false;
        try {
            if (mInputThread != null) {
                mInputThread.join(1000);
            }
            if (fileInputStream != null) {
                fileInputStream.close();
                fileInputStream = null;
            }
            if (fileOutputStream != null) {
                fileOutputStream.close();
                fileOutputStream = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void pushAudioFrame() {
        if (fileInputStream == null) {
            String baseDir = mContext.getFilesDir().getAbsolutePath();
            try {
                fileInputStream = new FileInputStream(baseDir + "/input_audio.pcm");
                Log.i(TAG, "fileInputStream start push, " + baseDir);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (fileInputStream == null) {
            Log.i(TAG, "fileInputStream is null");
            return;
        }
        final int len = 320;
        byte[] buffer = new byte[len];
        int i = 0;
        while (isInputAlive) {
            try {
                /** FIXME: 还有欢迎语播报，这里延时5秒 */
                for (; i < 500; i++) {
                    mEngine.pushAudioFrame(buffer, System.nanoTime(), SAMPLE_RATE, 1);
                    TimeUnit.MILLISECONDS.sleep(10);
                }

                int ret = fileInputStream.read(buffer, 0, len);
                if (ret < len) {
                    Log.i(TAG, "fileInputStream EOF");
                    break;
                }
                mEngine.pushAudioFrame(buffer, System.nanoTime(), SAMPLE_RATE, 1);
                TimeUnit.MILLISECONDS.sleep(10);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    public void renderAudioFrame(byte[] data, int sampleRate, int channelCount) {
        if (!isOutputAlive) {
            return;
        }

        if (fileOutputStream == null) {
            String baseDir = mContext.getFilesDir().getAbsolutePath();
            try {
                fileOutputStream = new FileOutputStream(baseDir + "/output_audio.pcm");
                Log.i(TAG, "FileOutputStream start pull, " + baseDir);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
//        Log.i(TAG, "renderAudioFrame, " + data.length + ", sampleRate:" + sampleRate + ", channels:" + channelCount);

        try {
            if (fileOutputStream != null) {
                fileOutputStream.write(data);
            }
            /** 模拟pcm播放耗时10ms */
            TimeUnit.MILLISECONDS.sleep(10);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
