package com.cooleshow.base.recorder;

import android.annotation.SuppressLint;
import android.content.Context;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.os.Build;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Base Recorder (Only record the original audio data.)
 *
 * @author maple
 * @time 2018/4/10.
 */
public class BaseDataRecorder implements Recorder {
    protected PullTransport pullTransport;
    protected AudioRecordConfig config;
    protected int bufferSizeInBytes;// 缓冲区大小
    protected File file;

    private AudioRecord audioRecord;
    private OutputStream outputStream;
    private ExecutorService executorService = Executors.newSingleThreadExecutor();


    protected BaseDataRecorder(File file, AudioRecordConfig config, PullTransport pullTransport) {
        this.file = file;
        this.config = config;
        this.pullTransport = pullTransport;
        // 计算缓冲区大小
        this.bufferSizeInBytes = AudioRecord.getMinBufferSize(
                config.getSampleRateInHz(),
                config.getChannelConfig(),
                config.getAudioFormat()
        );
    }

    @Override
    public void startRecording(Context context) {
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                startRecord(context);
            }
        });
    }

    @SuppressLint("MissingPermission")
    private void startRecord(Context context) {
        try {
            if (audioRecord == null) {
                audioRecord = new AudioRecord(config.getAudioSource(), config.getSampleRateInHz(),
                        config.getChannelConfig(), config.getAudioFormat(), bufferSizeInBytes);
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
                for (AudioDeviceInfo device : audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)) {
                    if (AudioDeviceInfo.TYPE_BUILTIN_MIC == device.getType()) {
                        audioRecord.setPreferredDevice(device);
                        break;
                    }

                }
            }
//            if (outputStream == null) {
//                outputStream = new FileOutputStream(file);
//            }
            audioRecord.startRecording();
            pullTransport.isEnableToBePulled(true);
            pullTransport.startPoolingAndWriting(audioRecord, bufferSizeInBytes, outputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void pauseRecording() {
        pullTransport.isEnableToBePulled(false);
    }

    @Override
    public void resumeRecording(Context context) {
        startRecording(context);
    }

    @Override
    public void stopRecording() {
        pauseRecording();

        if (audioRecord != null) {
            audioRecord.stop();
            audioRecord.release();
            audioRecord = null;
        }
        if (outputStream != null) {
            try {
                outputStream.flush();
                outputStream.close();
                outputStream = null;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
