package com.platform.plugs.live.handlers;

import com.alibaba.fastjson.JSON;
import com.aliyuncs.live.model.v20161101.*;
import com.platform.plugs.common.rpc.*;
import com.platform.plugs.live.config.LiveCasterConfig;
import com.platform.plugs.live.responseEntity.Caster;
import com.platform.plugs.live.responseEntity.CasterConfig;
import com.platform.plugs.live.responseEntity.CasterScenes;
import com.platform.plugs.live.responseEntity.StartCaster;
import com.platform.plugs.live.responseEntity.*;
import com.platform.plugs.live.utils.UTCDateFormat;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

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

/**
 * Description:
 * Author:zj
 * Date:2019/2/25 10:01
 */
public class LiveCasterHandler extends LiveHandler implements ILiveCasterHandler  {

    private final Log log = LogFactory.getLog(LiveCasterHandler.class);

    private LiveCasterConfig liveCasterConfig;

    private RpcResponse UNKNOWN_ERROR_RESPONSE = new RpcResponse(RpcResponse.ERROR_STATUS, ResponseResult.ERROR, ErrorCode.UnknownError.toString(), "unknown error");

    private RpcResponse PARAMS_ERROR_RESPONSE = new RpcResponse(RpcResponse.ERROR_STATUS, ResponseResult.ERROR, ErrorCode.ParamsError.toString(), "params error");

    public LiveCasterHandler(CommonRpc commonRpc) {
        super(commonRpc);
    }

    @Override
    public void configLiveCaster(LiveCasterConfig liveCasterConfig) {
        this.liveCasterConfig = liveCasterConfig;
    }

    @Override
    public RpcResponse<Caster> createCasterAndInitCasterConfig() {

        return createCasterAndInitCasterConfig(null);
    }

    @Override
    public RpcResponse<Caster> createCasterAndInitCasterConfig(String casterName) {

        RpcResponse<Caster> createResponse = createCaster(casterName);
        if(ResponseResult.SUCCESS != createResponse.getResult())
            return createResponse;
        Caster caster = createResponse.getResponse();
        RpcResponse initResponse = initCasterConfig(caster.getCasterId(), casterName);
        if(initResponse.getResult() != ResponseResult.SUCCESS) {
            log.error("createCasterAndInitCasterConfig error , errorCode : " + initResponse.getErrorCode() + " , errorMsg : " + initResponse.getErrorMsg());
            deleteCaster(caster.getCasterId());
            return initResponse;
        }
        RpcResponse<Caster> describeResponse = describeCaster(caster.getCasterId());

        return describeResponse;
    }

    @Override
    public RpcResponse<Caster> createCaster() {
        return createCaster(null, null, null);
    }

    @Override
    public RpcResponse<Caster> createCaster(String casterName) {
        return createCaster(casterName, null, null);
    }

    @Override
    public RpcResponse<Caster> createCaster(String casterName, String casterTemplate) {
        return createCaster(casterName, casterTemplate, null);
    }

    @Override
    public RpcResponse<Caster> createCaster(String casterName, String casterTemplate, Date expireTime) {

        CreateCasterRequest request = new CreateCasterRequest();
        String clientToken = UUID.randomUUID().toString().replaceAll("-", "");
        request.setClientToken(clientToken);//用于保证请求的幂等性。由客户端生成该参数值，要保证在不同请求间唯一，最大不值过 64 个 ASCII 字符
        int normType = 1;
        request.setNormType(normType);// 1:通用型，可以预监；0：播单型，不可预监
        String chargeType = "PostPaid";
        request.setChargeType(chargeType);//付费方式 PrePaid-预付费 PostPaid-后付费, 目前只支持PostPaid
        if(StringUtils.isNotBlank(casterName))//不填，默认为CasterId
            request.setCasterName(casterName);
        if("PrePaid".equals(chargeType)) {//PrePaid-预付费，必须预设分辨率，PostPaid预设无效
            if (StringUtils.isNotBlank(casterTemplate)) {
                //导播台预设分辨率，采用预付费方式时必输 lp_ld-流畅,lp_sd-标清,lp_hd-高清,lp_ud-超清,lp_ld_v-竖屏流畅,lp_sd_v-竖屏标清,lp_hd_v-竖屏高清,lp_ud_v-竖屏超清
                request.setCasterTemplate(casterTemplate);
            } else {
                request.setCasterTemplate(liveCasterConfig.getCasterTemplate());
            }
        }
        if(expireTime != null) {// 导播台过期时间
            request.setExpireTime(new UTCDateFormat().format(expireTime));
        }

        RpcResponse<Caster> createResponse = rpc(request, new ResponseWrapper<Caster, CreateCasterResponse>() {
            @Override
            public Caster responseWrap(CreateCasterResponse response) {
                Caster caster = new Caster();
                caster.setCasterId(response.getCasterId());
                return caster;
            }
        });

        if(ResponseResult.SUCCESS != createResponse.getResult()) {
            log.error("createCaster error , errorCode : " + createResponse.getErrorCode() + " , errorMsg : " + createResponse.getErrorMsg());
            return createResponse;
        }
        Caster createCaster = createResponse.getResponse();
        if(createCaster != null)
            return describeCaster(createCaster.getCasterId());
        else
            return UNKNOWN_ERROR_RESPONSE;
    }

    @Override
    public RpcResponse deleteCaster(String casterId) {
        DeleteCasterRequest request = new DeleteCasterRequest();
        request.setCasterId(casterId);
        return rpc(request);
    }

    @Override
    public RpcResponse<List<Caster>> describeCasters() {

        DescribeCastersRequest request = new DescribeCastersRequest();
        return rpc(request, new ResponseWrapper<List<Caster>, DescribeCastersResponse>() {
            @Override
            public List<Caster> responseWrap(DescribeCastersResponse response) {
                List<DescribeCastersResponse.Caster> dataList = response.getCasterList();
                List<Caster> result = new ArrayList<>();
                if(dataList == null || dataList.size() > 0)
                    return result;
                for (DescribeCastersResponse.Caster data : dataList) {
                    Caster caster = Caster.parse(data);
                    result.add(caster);
                }
                return result;
            }
        });
    }

    @Override
    public RpcResponse<Caster> describeCaster(String casterId) {

        DescribeCastersRequest request = new DescribeCastersRequest();
        if(StringUtils.isNotBlank(casterId))
            request.setCasterId(casterId);
        return rpc(request, new ResponseWrapper<Caster, DescribeCastersResponse>() {
            @Override
            public Caster responseWrap(DescribeCastersResponse response) {
                List<DescribeCastersResponse.Caster> dataList = response.getCasterList();
                if(dataList == null || dataList.size() != 1)
                    return null;
                DescribeCastersResponse.Caster data = dataList.get(0);
                Caster caster = Caster.parse(data);
                return caster;
            }
        });
    }

    @Override
    public RpcResponse<CasterConfig> describeCasterConfig(String casterId) {

        DescribeCasterConfigRequest request = new DescribeCasterConfigRequest();
        request.setCasterId(casterId);
        return rpc(request, new ResponseWrapper<CasterConfig, DescribeCasterConfigResponse>() {

            @Override
            public CasterConfig responseWrap(DescribeCasterConfigResponse response) {
                CasterConfig caster = CasterConfig.parse(response);
                return caster;
            }
        });
    }

    private RpcResponse initCasterConfig(String casterId, String casterName) {

        CasterConfig config = new CasterConfig();
        config.setCasterId(casterId);
        if(StringUtils.isNotBlank(casterName))
            config.setCasterName(casterName);

        CasterConfig.TranscodeConfig transcodeConfig = new CasterConfig.TranscodeConfig();
        transcodeConfig.setCasterTemplate(liveCasterConfig.getCasterTemplate());
        if(liveCasterConfig.getLiveTemplateIds() != null && liveCasterConfig.getLiveTemplateIds().size() > 0)
            transcodeConfig.setLiveTemplate(liveCasterConfig.getLiveTemplateIds());
        config.setTranscodeConfig(transcodeConfig);

        return setCasterConfig(config);
    }

    @Override
    public RpcResponse setCasterConfig(CasterConfig config){

        if(StringUtils.isBlank(config.getCasterId()))
            return PARAMS_ERROR_RESPONSE;
        SetCasterConfigRequest request = new SetCasterConfigRequest();
        request.setCasterId(config.getCasterId());
        request.setCasterName(config.getCasterName());
        request.setDomainName(liveCasterConfig.getDomain());

        if(config.getTranscodeConfig() != null)
            request.setTranscodeConfig(JSON.toJSONString(config.getTranscodeConfig()));
        if(config.getRecordConfig() != null)
            request.setRecordConfig(JSON.toJSONString(config.getRecordConfig()));

        request.setDelay(config.getDelay());
        request.setUrgentMaterialId(config.getUrgentMaterialId());
        request.setSideOutputUrl(config.getSideOutputUrl());
        request.setCallbackUrl(config.getCallbackUrl());
        request.setProgramName(config.getProgramName());
        request.setProgramEffect(config.getProgramEffect());
        request.setChannelEnable(config.getChannelEnable() == null ? 1 : config.getChannelEnable());

        return rpc(request);
    }

    @Override
    public RpcResponse<StartCaster> startCaster(String casterId) {

        StartCasterRequest request = new StartCasterRequest();
        request.setCasterId(casterId);
        return rpc(request, new ResponseWrapper<StartCaster, StartCasterResponse>() {

            @Override
            public StartCaster responseWrap(StartCasterResponse response) {
                StartCaster caster = StartCaster.parse(response);
                return caster;
            }
        });
    }

    @Override
    public RpcResponse stopCaster(String casterId) {

        StopCasterRequest request = new StopCasterRequest();
        request.setCasterId(casterId);
        return rpc(request);
    }

    @Override
    public RpcResponse<CasterScenes> describeCasterScenes(String casterId) {
        return describeCasterScenes(casterId, null);
    }

    @Override
    public RpcResponse<CasterScenes> describeCasterScenes(String casterId, String sceneId) {

        DescribeCasterScenesRequest request = new DescribeCasterScenesRequest();
        request.setCasterId(casterId);
        if(StringUtils.isNotBlank(sceneId))
            request.setSceneId(sceneId);

        return rpc(request, new ResponseWrapper<CasterScenes, DescribeCasterScenesResponse>() {
            @Override
            public CasterScenes responseWrap(DescribeCasterScenesResponse response) {
                CasterScenes casterScenes = CasterScenes.parse(response);
                return casterScenes;
            }
        });
    }

    @Override
    public RpcResponse copyCasterSceneConfig(String casterId, String fromSceneId, String toSceneId) {

        CopyCasterSceneConfigRequest request = new CopyCasterSceneConfigRequest();
        request.setCasterId(casterId);
        request.setFromSceneId(fromSceneId);
        request.setToSceneId(toSceneId);
        return rpc(request);
    }

    @Override
    public RpcResponse setCasterSceneConfig(String casterId, String sceneId, String layoutId, List<String> componentIds) {

        SetCasterSceneConfigRequest request = new SetCasterSceneConfigRequest();
        request.setCasterId(casterId);
        request.setSceneId(sceneId);
        request.setLayoutId(layoutId);
        if(componentIds != null)
            request.setComponentIds(componentIds);

        return rpc(request);
    }

    @Override
    public RpcResponse updateCasterSceneConfig(String casterId, String sceneId, String layoutId, List<String> componentIds) {

        UpdateCasterSceneConfigRequest request = new UpdateCasterSceneConfigRequest();
        request.setCasterId(casterId);
        request.setSceneId(sceneId);
        request.setLayoutId(layoutId);
        if(componentIds != null)
            request.setComponentIds(componentIds);

        return rpc(request);
    }

    @Override
    public RpcResponse deleteCasterSceneComponentConfig(String casterId, String sceneId) {
        return deleteCasterSceneConfig(casterId, sceneId, "Component");
    }

    @Override
    public RpcResponse deleteCasterSceneLayoutConfig(String casterId, String sceneId) {
        return deleteCasterSceneConfig(casterId, sceneId, "Layout");
    }

    @Override
    public RpcResponse deleteCasterSceneAllConfig(String casterId, String sceneId) {
        return deleteCasterSceneConfig(casterId, sceneId, "All");
    }

    private RpcResponse deleteCasterSceneConfig(String casterId, String sceneId, String type) {
        DeleteCasterSceneConfigRequest request = new DeleteCasterSceneConfigRequest();
        request.setCasterId(casterId);
        request.setSceneId(sceneId);
        request.setType(type);
        return rpc(request);
    }

    @Override
    public RpcResponse<String> startCasterScene(String casterId, String sceneId) {
        StartCasterSceneRequest request = new StartCasterSceneRequest();
        request.setCasterId(casterId);
        request.setSceneId(sceneId);
        return rpc(request, new ResponseWrapper<String, StartCasterSceneResponse>() {
            @Override
            public String responseWrap(StartCasterSceneResponse response) {
                return response.getStreamUrl();
            }
        });
    }

    @Override
    public RpcResponse stopCasterScene(String casterId, String sceneId) {
        StopCasterSceneRequest request = new StopCasterSceneRequest();
        request.setCasterId(casterId);
        request.setSceneId(sceneId);
        return rpc(request);
    }

    @Override
    public RpcResponse updateCasterSceneAudio(String casterId, String sceneId, Integer followEnable, List<AudioLayer> audioLayers,
                                              List<String> mixList) {
        UpdateCasterSceneAudioRequest request = new UpdateCasterSceneAudioRequest();
        request.setCasterId(casterId);
        request.setSceneId(sceneId);
        request.setFollowEnable(followEnable);
        if(audioLayers != null && audioLayers.size() > 0) {
            List<UpdateCasterSceneAudioRequest.AudioLayer> objs = new ArrayList<>();
            for (AudioLayer audioLayer : audioLayers) {
                UpdateCasterSceneAudioRequest.AudioLayer obj = new UpdateCasterSceneAudioRequest.AudioLayer();
                obj.setFixedDelayDuration(audioLayer.getFixedDelayDuration());
                obj.setValidChannel(audioLayer.getValidChannel());
                obj.setVolumeRate(audioLayer.getVolumeRate());
                objs.add(obj);
            }
            request.setAudioLayers(objs);
            request.setMixLists(mixList);
        }
        return rpc(request);
    }

    @Override
    public RpcResponse<CasterSceneAudio> describeCasterSceneAudio(String casterId, String sceneId) {

        DescribeCasterSceneAudioRequest request = new DescribeCasterSceneAudioRequest();
        request.setCasterId(casterId);
        request.setSceneId(sceneId);
        return rpc(request, new ResponseWrapper<CasterSceneAudio, DescribeCasterSceneAudioResponse>() {
            @Override
            public CasterSceneAudio responseWrap(DescribeCasterSceneAudioResponse response) {
                CasterSceneAudio casterSceneAudio = CasterSceneAudio.parse(response);
                return casterSceneAudio;
            }
        });
    }

    @Override
    public RpcResponse<CasterVideoResource> addCasterVideoResource(String casterId, String resourceName, String locationId) {
        return addCasterVideoResource(casterId, resourceName, locationId, null);
    }

    @Override
    public RpcResponse<CasterVideoResource> addCasterVideoLiveStreamResource(String casterId, String resourceName, String locationId, String liveStreamUrl) {
        return addCasterVideoResource(casterId, resourceName, locationId, liveStreamUrl);
    }

    private RpcResponse<CasterVideoResource> addCasterVideoResource(String casterId, String resourceName, String locationId, String liveStreamUrl) {

        AddCasterVideoResourceRequest request = new AddCasterVideoResourceRequest();
        request.setCasterId(casterId);
        request.setResourceName(resourceName);
        request.setLocationId(locationId);
        request.setLiveStreamUrl(liveStreamUrl);

        return rpc(request, new ResponseWrapper<CasterVideoResource, AddCasterVideoResourceResponse>() {

            @Override
            public CasterVideoResource responseWrap(AddCasterVideoResourceResponse response) {
                CasterVideoResource resource = new CasterVideoResource();
                resource.setResourceId(response.getResourceId());
                return resource;
            }
        });
    }

    @Override
    public RpcResponse deleteCasterVideoResource(String casterId, String resourceId) {

        DeleteCasterVideoResourceRequest request = new DeleteCasterVideoResourceRequest();
        request.setCasterId(casterId);
        request.setResourceId(resourceId);
        return rpc(request);
    }

    @Override
    public RpcResponse modifyCasterVideoLiveStreamResource(String casterId, String resourceId, String resourceName, String liveStreamUrl) {

        ModifyCasterVideoResourceRequest request = new ModifyCasterVideoResourceRequest();
        request.setCasterId(casterId);
        request.setResourceId(resourceId);
        request.setResourceName(resourceName);
        request.setLiveStreamUrl(liveStreamUrl);
        return rpc(request);
    }

    @Override
    public RpcResponse<List<CasterVideoResource>> describeCasterVideoResources(String casterId) {

        DescribeCasterVideoResourcesRequest request = new DescribeCasterVideoResourcesRequest();
        request.setCasterId(casterId);
        return rpc(request, new ResponseWrapper<List<CasterVideoResource>, DescribeCasterVideoResourcesResponse>() {

            @Override
            public List<CasterVideoResource> responseWrap(DescribeCasterVideoResourcesResponse response) {
                List<DescribeCasterVideoResourcesResponse.VideoResource> dataList = response.getVideoResources();
                List<CasterVideoResource> resources = new ArrayList<>();
                if (dataList != null && dataList.size() > 0) {
                    for (DescribeCasterVideoResourcesResponse.VideoResource videoResource : dataList) {
                        CasterVideoResource resource = CasterVideoResource.parse(videoResource);
                        resources.add(resource);
                    }
                }
                return resources;
            }
        });
    }

    @Override
    public RpcResponse addCasterLayout(String casterId, List<VideoLayer> videoLayers, List<AudioLayer> audioLayers,
                                       List<String> blendList, List<String> mixList) {

        AddCasterLayoutRequest request = new AddCasterLayoutRequest();
        request.setCasterId(casterId);
        List<AddCasterLayoutRequest.AudioLayer> requestAudioLayers = new ArrayList<>();
        List<AddCasterLayoutRequest.VideoLayer> requestVideoLayers = new ArrayList<>();

        for (VideoLayer obj : videoLayers) {
            AddCasterLayoutRequest.VideoLayer videoLayer = new AddCasterLayoutRequest.VideoLayer();
            videoLayer.setFillMode(obj.getFillMode());
            videoLayer.setFixedDelayDuration(obj.getFixedDelayDuration());
            videoLayer.setHeightNormalized(obj.getHeightNormalized());
            videoLayer.setPositionNormalizeds(obj.getPositionNormalized());
            videoLayer.setPositionRefer(obj.getPositionRefer());
            videoLayer.setWidthNormalized(obj.getWidthNormalized());
            requestVideoLayers.add(videoLayer);
        }
        for (AudioLayer obj : audioLayers) {
            AddCasterLayoutRequest.AudioLayer audioLayer = new AddCasterLayoutRequest.AudioLayer();
            audioLayer.setFixedDelayDuration(obj.getFixedDelayDuration());
            audioLayer.setValidChannel(obj.getValidChannel());
            audioLayer.setVolumeRate(obj.getVolumeRate());
            requestAudioLayers.add(audioLayer);
        }
        request.setVideoLayers(requestVideoLayers);
        request.setAudioLayers(requestAudioLayers);
        request.setBlendLists(blendList);
        request.setMixLists(mixList);
        return rpc(request, new ResponseWrapper<CasterLayout, AddCasterLayoutResponse>() {

            @Override
            public CasterLayout responseWrap(AddCasterLayoutResponse response) {
                CasterLayout layout = new CasterLayout();
                layout.setLayOutId(response.getLayoutId());
                return layout;
            }
        });
    }

    @Override
    public RpcResponse deleteCasterLayout(String casterId, String layoutId) {

        DeleteCasterLayoutRequest request = new DeleteCasterLayoutRequest();
        request.setCasterId(casterId);
        request.setLayoutId(layoutId);
        return rpc(request);
    }

    @Override
    public RpcResponse<List<CasterLayout>> describeCasterLayouts(String casterId, String layoutId) {

        DescribeCasterLayoutsRequest request = new DescribeCasterLayoutsRequest();
        request.setCasterId(casterId);
        request.setLayoutId(layoutId);
        return rpc(request, new ResponseWrapper<List<CasterLayout>, DescribeCasterLayoutsResponse>() {

            @Override
            public List<CasterLayout> responseWrap(DescribeCasterLayoutsResponse response) {
                List<DescribeCasterLayoutsResponse.Layout> layouts = response.getLayouts();
                List<CasterLayout> list = new ArrayList<>();
                if (layouts != null || layouts.size() > 0) {
                    for (DescribeCasterLayoutsResponse.Layout layout : layouts) {
                        CasterLayout casterLayout = CasterLayout.parse(layout);
                        list.add(casterLayout);
                    }
                }
                return list;
            }
        });
    }

    @Override
    public RpcResponse modifyCasterLayout(String casterId, String layoutId, List<VideoLayer> videoLayers,
                                          List<AudioLayer> audioLayers, List<String> blendList, List<String> mixList) {

        ModifyCasterLayoutRequest request = new ModifyCasterLayoutRequest();
        List<ModifyCasterLayoutRequest.AudioLayer> requestAudioLayers = new ArrayList<>();
        List<ModifyCasterLayoutRequest.VideoLayer> requestVideoLayers = new ArrayList<>();
        if (videoLayers != null && videoLayers.size() > 0) {
            for (VideoLayer obj : videoLayers) {
                ModifyCasterLayoutRequest.VideoLayer videoLayer = new ModifyCasterLayoutRequest.VideoLayer();
                videoLayer.setFillMode(obj.getFillMode());
                videoLayer.setFixedDelayDuration(obj.getFixedDelayDuration());
                videoLayer.setHeightNormalized(obj.getHeightNormalized());
                videoLayer.setPositionNormalizeds(obj.getPositionNormalized());
                videoLayer.setPositionRefer(obj.getPositionRefer());
                videoLayer.setWidthNormalized(obj.getWidthNormalized());
                requestVideoLayers.add(videoLayer);
            }
        }

        if (audioLayers != null && audioLayers.size() > 0) {
            for (AudioLayer obj : audioLayers) {
                ModifyCasterLayoutRequest.AudioLayer audioLayer = new ModifyCasterLayoutRequest.AudioLayer();
                audioLayer.setFixedDelayDuration(obj.getFixedDelayDuration());
                audioLayer.setValidChannel(obj.getValidChannel());
                audioLayer.setVolumeRate(obj.getVolumeRate());
                requestAudioLayers.add(audioLayer);
            }
        }
        request.setCasterId(casterId);
        request.setLayoutId(layoutId);
        request.setAudioLayers(requestAudioLayers);
        request.setVideoLayers(requestVideoLayers);
        request.setBlendLists(blendList);
        request.setMixLists(mixList);
        return rpc(request);
    }

    @Override
    public RpcResponse<List<Channel>> describeCasterChannels(String casterId) {
        DescribeCasterChannelsRequest request = new DescribeCasterChannelsRequest();
        request.setCasterId(casterId);
        return rpc(request, new ResponseWrapper<List<Channel>, DescribeCasterChannelsResponse>() {

            @Override
            public List<Channel> responseWrap(DescribeCasterChannelsResponse response) {
                List<DescribeCasterChannelsResponse.Channel> channels = response.getChannels();
                List<Channel> list = new ArrayList<>();
                if (channels != null || channels.size() > 0) {
                    for (DescribeCasterChannelsResponse.Channel obj : channels) {
                        Channel channel = Channel.parse(obj);
                        list.add(channel);
                    }
                }
                return list;
            }
        });
    }

    @Override
    public RpcResponse setCasterChannel(String casterId, String channelId, String resourceId, Integer seekOffset, Integer playStatus) {
        SetCasterChannelRequest request = new SetCasterChannelRequest();
        request.setCasterId(casterId);
        request.setChannelId(channelId);
        request.setPlayStatus(playStatus);
        request.setResourceId(resourceId);
        request.setSeekOffset(seekOffset);
        return rpc(request);
    }

    @Override
    public RpcResponse<CasterComponent> addCasterComponent(String casterId, String componentName, String locationId, String componentType, String effect, CasterComponent.ComponentLayer componentLayer, CasterComponent.TextLayerContent textLayerContent, CasterComponent.ImageLayerContent imageLayerContent, CasterComponent.CaptionLayerContent captionLayerContent) {
        AddCasterComponentRequest request = new AddCasterComponentRequest();
        request.setCasterId(casterId);
        request.setComponentName(componentName);
        request.setLocationId(locationId);
        request.setComponentType(componentType);
        request.setEffect(effect);
        if(componentLayer != null)
            request.setComponentLayer(JSON.toJSONString(componentLayer));
        if(textLayerContent != null)
            request.setTextLayerContent(JSON.toJSONString(textLayerContent));
        if(imageLayerContent != null)
            request.setImageLayerContent(JSON.toJSONString(imageLayerContent));
        if(captionLayerContent != null)
         request.setCaptionLayerContent(JSON.toJSONString(captionLayerContent));
        return rpc(request, new ResponseWrapper<CasterComponent, AddCasterComponentResponse>() {
            @Override
            public CasterComponent responseWrap(AddCasterComponentResponse response) {
                CasterComponent casterComponent = new CasterComponent();
                casterComponent.setComponentId(response.getComponentId());
                return casterComponent;
            }
        });
    }

    @Override
    public RpcResponse deleteCasterComponent(String casterId, String componentId) {
        DeleteCasterComponentRequest request = new DeleteCasterComponentRequest();
        request.setCasterId(casterId);
        request.setComponentId(componentId);
        return rpc(request);
    }

    @Override
    public RpcResponse modifyCasterComponent(String casterId, String componentId, String componentName, String componentType, String effect, CasterComponent.ComponentLayer componentLayer, CasterComponent.TextLayerContent textLayerContent, CasterComponent.ImageLayerContent imageLayerContent, CasterComponent.CaptionLayerContent captionLayerContent) {
        ModifyCasterComponentRequest request = new ModifyCasterComponentRequest();
        request.setCasterId(casterId);
        request.setComponentName(componentName);
        request.setComponentId(componentId);
        request.setComponentType(componentType);
        request.setEffect(effect);
        if(componentLayer != null)
            request.setComponentLayer(JSON.toJSONString(componentLayer));
        if(textLayerContent != null)
            request.setTextLayerContent(JSON.toJSONString(textLayerContent));
        if(imageLayerContent != null)
            request.setImageLayerContent(JSON.toJSONString(imageLayerContent));
        if(captionLayerContent != null)
            request.setCaptionLayerContent(JSON.toJSONString(captionLayerContent));
        return rpc(request);
    }

    @Override
    public RpcResponse<List<CasterComponent>> describeCasterComponents(String casterId, String componentId) {
        DescribeCasterComponentsRequest request = new DescribeCasterComponentsRequest();
        request.setCasterId(casterId);request.setComponentId(componentId);
        return rpc(request, new ResponseWrapper<List<CasterComponent>, DescribeCasterComponentsResponse>() {
            @Override
            public List<CasterComponent> responseWrap(DescribeCasterComponentsResponse response) {
                List<CasterComponent> components = new ArrayList<>();
                if(response.getTotal() > 0) {
                    List<DescribeCasterComponentsResponse.Component> dataList = response.getComponents();
                    for (DescribeCasterComponentsResponse.Component data : dataList) {
                        CasterComponent component = CasterComponent.parse(data);
                        components.add(component);
                    }
                }
                return components;
            }
        });
    }

    @Override
    public RpcResponse<List<CasterStream>> describeCasterStreamUrl(String casterId) {
        DescribeCasterStreamUrlRequest request = new DescribeCasterStreamUrlRequest();
        request.setCasterId(casterId);
        return rpc(request, new ResponseWrapper<List<CasterStream>, DescribeCasterStreamUrlResponse>() {
            @Override
            public List<CasterStream> responseWrap(DescribeCasterStreamUrlResponse response) {
                List<CasterStream> casterStreams = new ArrayList<>();
                if(response.getCasterStreams() != null && response.getCasterStreams().size() > 0) {
                    for (DescribeCasterStreamUrlResponse.CasterStream obj : response.getCasterStreams()) {
                        CasterStream casterStream = CasterStream.parse(obj);
                        casterStreams.add(casterStream);
                    }
                }
                return casterStreams;
            }
        });
    }

    @Override
    public RpcResponse effectCasterUrgent(String casterId, String sceneId) {
        EffectCasterUrgentRequest request  = new EffectCasterUrgentRequest();
        request.setCasterId(casterId);
        request.setSceneId(sceneId);
        return rpc(request);
    }

    @Override
    public RpcResponse effectCasterVideoResource(String casterId, String sceneId, String resourceId) {
        EffectCasterVideoResourceRequest request = new EffectCasterVideoResourceRequest();
        request.setCasterId(casterId);
        request.setSceneId(sceneId);
        request.setResourceId(resourceId);
        return rpc(request);
    }
}
