package com.platform.plugs.live.handlers;

import com.aliyuncs.live.model.v20161101.*;
import com.platform.plugs.common.rpc.*;
import com.platform.plugs.live.responseEntity.LiveRecordVodConfig;
import com.platform.plugs.live.responseEntity.LiveStreamOnline;
import com.platform.plugs.live.utils.UTCDateFormat;
import com.platform.plugs.live.annotation.RpcParam;
import com.platform.plugs.live.config.LiveRecordConfig;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 *
 * @Author TONG
 * @Date 2019/2/18 10:18
 **/
public class LiveRecordHandler extends LiveHandler implements ILiveRecordHandler {

    private LiveRecordConfig liveRecordConfig;

    private ILiveStreamHandler liveStreamHandler;

    public LiveRecordHandler(CommonRpc commonRpc, ILiveStreamHandler liveStreamHandler) {
        super(commonRpc);
        this.liveStreamHandler = liveStreamHandler;
    }

    @Override
    public LiveRecordConfig getLiveRecordConfig() {
        return this.liveRecordConfig;
    }

    @Override
    public void configLiveRecord(LiveRecordConfig liveRecordConfig) {
        this.liveRecordConfig = liveRecordConfig;
    }

    /**
     * 配置 APP 录制，输出内容保存到 OSS 中,并开启在线流录制
     * @param appName
     * @param streamName
     * @return
     */
    public RpcResponse addLiveAppRecordConfigAndStartOnlineSteamRecords(String appName, String streamName) {

        RpcResponse response = addLiveAppRecordConfig(appName, streamName, null, null);
        if(response.getResult() != ResponseResult.SUCCESS) {
            deleteLiveAppRecordConfig(appName, streamName);
            return response;
        }

        List<LiveStreamOnline> onlineStreams = liveStreamHandler.describeLiveStreamsOnlineList(appName, null);

        if(onlineStreams != null && onlineStreams.size() > 0) {
            for (LiveStreamOnline obj : onlineStreams) {
                RpcResponse startResponse = startRealTimeRecordCommand(obj.getAppName(), obj.getStreamName());
                if (startResponse.getResult() != ResponseResult.SUCCESS) {
                    // 正在录制的流删除配置，在线流录制但不回调
                    deleteLiveAppRecordConfig(appName, streamName);
                    return startResponse;
                }
            }
        }
        return response;
    }

    /**
     * 配置 APP 录制，输出内容保存到 OSS 中
     * @param appName
     * @param streamName
     * @return
     */
    public RpcResponse addLiveAppRecordConfig(String appName, String streamName) {

        return addLiveAppRecordConfig(appName, streamName, null, null);
    }

    @Override
    public RpcResponse addLiveAppRecordConfig(String appName, String streamName, Date endDate) {
        return addLiveAppRecordConfig(appName, streamName, null, endDate);
    }

    /**
     * 配置 APP 录制，输出内容保存到 OSS 中
     * @param appName
     * @param streamName
     * @param startTime
     * @param endTime
     * @return
     */
    public RpcResponse addLiveAppRecordConfig(String appName, String streamName, Date startTime, Date endTime) {

        AddLiveAppRecordConfigRequest request = new AddLiveAppRecordConfigRequest();
        request.setDomainName(liveRecordConfig.getDomainName());
        request.setOssBucket(liveRecordConfig.getOssBucket());
        request.setOssEndpoint(liveRecordConfig.getOssEndpoint());
        List<AddLiveAppRecordConfigRequest.RecordFormat> recordFormats = new ArrayList<>();
        AddLiveAppRecordConfigRequest.RecordFormat recordFormat = new AddLiveAppRecordConfigRequest.RecordFormat();
        if(liveRecordConfig.getOnDemand() != null)
            request.setOnDemand(liveRecordConfig.getOnDemand());
        if(liveRecordConfig.getCycleDuration() != null)
            recordFormat.setCycleDuration(liveRecordConfig.getCycleDuration());
        if(org.apache.commons.lang.StringUtils.isNotBlank(liveRecordConfig.getFormat()))
            recordFormat.setFormat(liveRecordConfig.getFormat());
        if(org.apache.commons.lang.StringUtils.isNotBlank(liveRecordConfig.getOssObjectPrefix()))
            recordFormat.setOssObjectPrefix(liveRecordConfig.getOssObjectPrefix());
        if(org.apache.commons.lang.StringUtils.isNotBlank(liveRecordConfig.getSliceOssObjectPrefix()))
            recordFormat.setSliceOssObjectPrefix(liveRecordConfig.getSliceOssObjectPrefix());
        recordFormats.add(recordFormat);
        request.setRecordFormats(recordFormats);
        request.setAppName(appName);
        request.setStreamName(streamName);
        if(startTime != null) {
            request.setStartTime(new UTCDateFormat().format(startTime));
        }
        if(endTime != null) {
            request.setStartTime(new UTCDateFormat().format(endTime));
        }
        return rpc(request);
    }

//    private RpcResponse addLiveAppRecordConfig(String appName, String streamName, Date startTime, Date endTime) {

//        AddLiveRecordNotifyConfigEntity request = new AddLiveRecordNotifyConfigEntity();
//        request.setDomainName(liveRecord.getDomainName());
//        request.setOssBucket(liveRecord.getOssBucket());
//        request.setOssEndpoint(liveRecord.getOssEndpoint());
//        if(liveRecord.getOnDemand() != null)
//            request.setOnDemand(liveRecord.getOnDemand());
//        if(liveRecord.getCycleDuration() != null)
//            request.setCycleDuration(liveRecord.getCycleDuration());
//        if(StringUtils.isNotBlank(liveRecord.getFormat()))
//            request.setFormat(liveRecord.getFormat());
//        if(StringUtils.isNotBlank(liveRecord.getOssObjectPrefix()))
//            request.setOssObjectPrefix(liveRecord.getOssObjectPrefix());
//        if(StringUtils.isNotBlank(liveRecord.getSliceOssObjectPrefix()))
//            request.setSliceOssObjectPrefix(liveRecord.getSliceOssObjectPrefix());
//
//        request.setAppName(appName);
//        request.setStreamName(streamName);
//        if(startTime != null) {
//            request.setStartTime(new UTCDateFormat().format(startTime));
//        }
//        if(endTime != null) {
//            request.setStartTime(new UTCDateFormat().format(endTime));
//        }
//        return rpc("AddLiveAppRecordConfig", MethodType.POST, request);
//    }

    /**
     * 删除录制配置并停止所有在线流录制,已在录制的流会继续录制完毕，由于配置已删除，所以没有回调
     * @param appName
     * @param streamName
     * @return
     */
    public RpcResponse deleteLiveAppRecordConfigAndStopOnlineSteamRecords(String appName, String streamName) {
        RpcResponse response = null;
        List<LiveStreamOnline> onlineStreams = liveStreamHandler.describeLiveStreamsOnlineList(appName, null);
        if(onlineStreams != null && onlineStreams.size() > 0)
            for (LiveStreamOnline obj : onlineStreams) {
                RpcResponse stopResponse = stopRealTimeRecordCommand(obj.getAppName(), obj.getStreamName());
                response= stopResponse;
                if(stopResponse.getResult() != ResponseResult.SUCCESS)
                    return stopResponse;
            }
        response = deleteLiveAppRecordConfig(appName, streamName);
        if(response.getResult() != ResponseResult.SUCCESS) return response;
        return response;
    }

    /**
     * 删除录制配置
     * @param appName
     * @param streamName
     * @return
     */
    public RpcResponse deleteLiveAppRecordConfig(String appName, String streamName) {
        DeleteLiveAppRecordConfigRequest request = new DeleteLiveAppRecordConfigRequest();
        request.setDomainName(liveRecordConfig.getDomainName());
        request.setAppName(appName);
        request.setStreamName(streamName);
        return rpc(request);
    }

    /**
     * 启动录制
     * @param appName
     * @param streamName
     * @return
     */
    public RpcResponse startRealTimeRecordCommand(String appName, String streamName) {
        return commondRealTimeRecordCommand(appName, streamName, "start");
    }

    /**
     * 停止录制
     * @param appName
     * @param streamName
     * @return
     */
    public RpcResponse stopRealTimeRecordCommand(String appName, String streamName) {
        return commondRealTimeRecordCommand(appName, streamName, "stop");
    }

    /**
     * 动态启动停止直播录制
     * @param appName
     * @param streamName
     * @param command
     * @return
     */
    private RpcResponse commondRealTimeRecordCommand(String appName, String streamName, String command) {
        RealTimeRecordCommandRequest request = new RealTimeRecordCommandRequest();
        request.setDomainName(liveRecordConfig.getDomainName());
        request.setAppName(appName);
        request.setStreamName(streamName);
        request.setCommand(command);
        return rpc(request);
    }

    @Override
    public RpcResponse addLiveRecordVodMp4Config(String appName, String streamName) {
        AddLiveRecordVodConfigRequest request = new AddLiveRecordVodConfigRequest();
        request.setAppName(appName);
        request.setStreamName(streamName);
        request.setVodTranscodeGroupId(liveRecordConfig.getVodTranscodeGroupIdMp4());
        request.setDomainName(liveRecordConfig.getDomainName());
        request.setCycleDuration(liveRecordConfig.getCycleDuration());
        return rpc(request);
    }

    @Override
    public RpcResponse addLiveRecordVodMp3Config(String appName, String streamName) {
        AddLiveRecordVodConfigRequest request = new AddLiveRecordVodConfigRequest();
        request.setAppName(appName);
        request.setStreamName(streamName);
        request.setVodTranscodeGroupId(liveRecordConfig.getVodTranscodeGroupIdMp3());
        request.setDomainName(liveRecordConfig.getDomainName());
        request.setCycleDuration(liveRecordConfig.getCycleDuration());
        return rpc(request);
    }

    @Override
    public RpcResponse deleteLiveRecordVodConfig(String appName, String streamName) {
        DeleteLiveRecordVodConfigRequest request = new DeleteLiveRecordVodConfigRequest();
        request.setAppName(appName);
        request.setStreamName(streamName);
        request.setDomainName(liveRecordConfig.getDomainName());
        return rpc(request);
    }

    @Override
    public RpcResponse<List<LiveRecordVodConfig>> describeLiveRecordVodConfigs() {

        DescribeLiveRecordVodConfigsRequest request = new DescribeLiveRecordVodConfigsRequest();
        request.setDomainName(liveRecordConfig.getDomainName());
        request.setPageSize(100l);//100条
        return rpc(request, new ResponseWrapper<List<LiveRecordVodConfig>, DescribeLiveRecordVodConfigsResponse>() {

            @Override
            public List<LiveRecordVodConfig> responseWrap(DescribeLiveRecordVodConfigsResponse response) {
                List<DescribeLiveRecordVodConfigsResponse.LiveRecordVodConfig> datas = response.getLiveRecordVodConfigs();
                List<LiveRecordVodConfig> result = new ArrayList<>();
                if(datas != null && datas.size() > 0) {
                    for(DescribeLiveRecordVodConfigsResponse.LiveRecordVodConfig data : datas) {
                        LiveRecordVodConfig liveRecordVodConfig = LiveRecordVodConfig.parse(data);
                        result.add(liveRecordVodConfig);
                    }
                }
                return result;
            }
        });
    }
    
    /**
     * 查询现场直转点配置列表
     * @return
     */
    @Override
    public RpcResponse<List<LiveRecordVodConfig>> describeLiveRecordVodConfig(@RpcParam String appName){
    	DescribeLiveRecordVodConfigsRequest request = new DescribeLiveRecordVodConfigsRequest();
        request.setDomainName(liveRecordConfig.getDomainName());
        request.setAppName(appName);
        request.setPageSize(100l);//100条
        return rpc(request, new ResponseWrapper<List<LiveRecordVodConfig>, DescribeLiveRecordVodConfigsResponse>() {

            @Override
            public List<LiveRecordVodConfig> responseWrap(DescribeLiveRecordVodConfigsResponse response) {
                List<DescribeLiveRecordVodConfigsResponse.LiveRecordVodConfig> datas = response.getLiveRecordVodConfigs();
                List<LiveRecordVodConfig> result = new ArrayList<>();
                if(datas != null && datas.size() > 0) {
                    for(DescribeLiveRecordVodConfigsResponse.LiveRecordVodConfig data : datas) {
                        LiveRecordVodConfig liveRecordVodConfig = LiveRecordVodConfig.parse(data);
                        result.add(liveRecordVodConfig);
                    }
                }
                return result;
            }
        });
    }
}
