package cn.tee3.manager.service;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.util.Log;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import cn.tee3.avd.AVDEngine;
import cn.tee3.avd.ErrorCode;
import cn.tee3.avd.RoomInfo;
import cn.tee3.manager.bean.CommonBean;
import cn.tee3.manager.bean.RxBusMsgObj;
import cn.tee3.manager.bean.ScheduleRoomBean;
import cn.tee3.manager.util.FileManager;
import cn.tee3.manager.util.RxBus;
import cn.tee3.manager.util.StringUtils;

public class EngineConfigure implements IBaseService {

    private static final String CREATE_ROOM_FAILURE_STR = "创建房间失败，errorCode=";

    private static Context context;
    private String tag = "EngineConfigure";
    private AVDEngineCreateRoomListener listener;
    private String logPath = "";
    private boolean isLogParamsConfigured;

    private EngineConfigure() {
    }

    public static EngineConfigure getInstance() {
        return Builder.INSTANCE;
    }

    public static EngineConfigure getInstance(Context context) {
        EngineConfigure.context = context.getApplicationContext();
        return Builder.INSTANCE;
    }

    private static class Builder {
        private static final EngineConfigure INSTANCE = new EngineConfigure();
    }

    /**
     * 引擎初始化
     *
     * @return
     */
    @Override
    public String init() {
        if (context == null) {
            Log.e(tag, "context为空！");
            return IBaseService.FAILURE;
        }
        logFileConfig();
        setAVDEngineOptions();
        engineSetup();
        return IBaseService.SUCCESS;
    }

    public String init(Context context) {
        EngineConfigure.context = context.getApplicationContext();
        return init();
    }

    /**
     * 引擎释放
     */
    @Override
    public void dispose() {
        engineRelease();
        context = null;
        logPath = "";
        isLogParamsConfigured = false;
    }

    public boolean isWorking() {
        return AVDEngine.instance().isWorking();
    }

    public AVDEngine getAVDEngine() {
        return AVDEngine.instance();
    }

    /**
     * AVDSDK日志配置
     */
    public void logFileConfig() {
        if (isLogParamsConfigured) {
            return;
        }
        int permission = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (Environment.isExternalStorageEmulated() && permission == PackageManager.PERMISSION_GRANTED) {
            if (TextUtils.isEmpty(logPath)) {
                @SuppressLint("SimpleDateFormat") DateFormat format = new SimpleDateFormat("yyyyMMdd_HHmmss");
                //            String dumpPath = "doubleRecord/" + "doubleRecord" + format.format(new Date()) + ".dump";
                logPath = "doubleRecord/" + "doubleRecord" + format.format(new Date()) + ".log";
                logPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + logPath;
                //        AVDEngine.instance().setDumpFile(dumpPath);
            }
            String params = CommonBean.LogParams.debug.name() + " " + AVDManager.getInstance().getSetting().getLogLevel().name() + " "
                    + CommonBean.LogParams.stats.name() + " " + CommonBean.LogParams.append.name() + " " + CommonBean.LogParams.realtstamp.name();
            AVDEngine.instance().setLogParams(params, logPath);
            isLogParamsConfigured = true;
        }
    }

    /**
     * 启动引擎
     */
    public void engineSetup() {
        int ret;
        if (AVDEngine.instance().isWorking()) {
            RxBus.getInstance().post(new RxBusMsgObj(RxBusMsgObj.MsgTag.AVDEngine_onInitResult, ErrorCode.AVD_OK));
            return;
        }
        Setting.AVDAuthentication authentication = AVDManager.getInstance().getAuthentication();

        if (TextUtils.isEmpty(authentication.getToken())) {
            ret = AVDEngine.instance().init(context, CallbackManager.getInstance().getAvdEngineCallback(), authentication.getAvd_server(), authentication.getApp_key(), authentication.getSecret_key());
        } else {
            ret = AVDEngine.instance().init(context, CallbackManager.getInstance().getAvdEngineCallback(), authentication.getAvd_server(), authentication.getToken());
        }

        if (ErrorCode.AVD_OK != ret) {
            Log.e(tag, "engineSetup() -> init AVDEngine failed. ret=" + ret);
            RxBus.getInstance().post(new RxBusMsgObj(RxBusMsgObj.MsgTag.AVDEngine_onInitResult, 1008));
        }
    }

    /**
     * 设置AVDSDK引擎选项
     */
    private void setAVDEngineOptions() {
        Setting.AVDOption options = AVDManager.getInstance().getSetting();
        AVDEngine.instance().setOption(AVDEngine.Option.eo_video_swapwh_by_rotation, "false");
        AVDEngine.instance().setOption(AVDEngine.Option.eo_camera_mode_frontback, "true");
        AVDEngine.instance().setOption(AVDEngine.Option.eo_video_resolution_16balign, "true");
        AVDEngine.instance().setOption(AVDEngine.Option.eo_camera_capability_default, options.getResolution().getValue());
        AVDEngine.instance().setOption(AVDEngine.Option.eo_video_codec_hw_priority, "true");
        AVDEngine.instance().setOption(AVDEngine.Option.eo_audio_aec_Enable, "true");
        AVDEngine.instance().setOption(AVDEngine.Option.eo_audio_aec_DAEcho_Enable, "false");
        AVDEngine.instance().setOption(AVDEngine.Option.eo_audio_autoGainControl_Enable, "true");
        AVDEngine.instance().setOption(AVDEngine.Option.eo_video_renderusecapture, "true");
        AVDEngine.instance().setOption(AVDEngine.Option.eo_video_codec_priority, options.getCodecType().getValue());
        AVDEngine.instance().setOption(AVDEngine.Option.eo_video_codec_hw_encode, options.isHardwareEncode() ? "true" : "false");
        AVDEngine.instance().setOption(AVDEngine.Option.eo_video_codec_hw_decode, options.isHardwareDecode() ? "true" : "false");
        AVDEngine.instance().setOption(AVDEngine.Option.eo_data_channel_tcp_priority, "false");
        AVDEngine.instance().setOption(AVDEngine.Option.eo_auto_change_resolution, "false");
    }

    /**
     * 创建房间
     *
     * @param roomInfo 房间参数（房间模式参考 cn.tee3.avd.RoomInfo.java 类，一般情况下使用 RoomInfo.RoomMode_mcu 模式 ）
     */
    public void createRoom(RoomInfo roomInfo, AVDEngineCreateRoomListener listener) {
        this.listener = listener;
        if (!AVDEngine.instance().isWorking() && listener != null) {
            listener.error("AVD SDK 引擎尚未初始化，请先调用 AVDManager.permissionHelper().request(...) 申请动态权限，权限申请成功回调后再调用 AVDManager.permissionHelper().initAVDEngine(...) 初始化引擎！");
            return;
        }
        int i = AVDEngine.instance().scheduleRoom(roomInfo);
        if (i != ErrorCode.AVD_OK && listener != null) {
            listener.error(EngineConfigure.CREATE_ROOM_FAILURE_STR + i);
        }
    }

    public void createRoomCallback(ScheduleRoomBean bean) {
        if (listener != null) {
            if (bean.getResult() == ErrorCode.AVD_OK || bean.getResult() == 40005 || bean.getResult() == 40003) {
                listener.success(bean.getResult() == 40005 ? RoomManager.getRoomParams().getRoomId() : bean.getRoomId());
            } else {
                listener.error(EngineConfigure.CREATE_ROOM_FAILURE_STR + bean.getResult());
            }
        }
    }

    public void engineRelease() {
        if (AVDEngine.instance().isWorking()) {
            AVDEngine.instance().uninit();
        }
    }

    public interface AVDEngineCreateRoomListener {

        void success(String roomId);

        void error(String errorCode);
    }
}
