package com.platform.plugs.common.rpc;

import com.alibaba.druid.util.StringUtils;
import com.aliyuncs.*;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.live.model.v20161101.DeleteLiveAppRecordConfigRequest;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.http.MethodType;
import com.google.gson.Gson;
import com.platform.plugs.live.annotation.RpcEntity;
import com.platform.plugs.live.annotation.RpcField;
import com.platform.plugs.live.config.LivePullStreamConfig;
import lombok.Data;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLDecoder;
import java.util.*;

/**
 * @Author TONG
 * @Date 2019/2/18 16:03
 **/
@Data
public class CommonRpc {

    private String[] SCAN_PACKAGE = {"com.platform.plugs.live.rpcEntity"};
    private Profile profile;

    private DefaultProfile defaultProfile;
    private IAcsClient client;

    private DefaultRequestParams defaultRequestParams;

    private Map<String, Map<String, String>> rpcEntityMap;

    List<Class> clazzs = new ArrayList<>();

    public CommonRpc(Profile profile, DefaultRequestParams defaultRequestParams) {
        this.profile = profile;
        this.defaultRequestParams = defaultRequestParams;
        this.init();
    }

    public void init() {
        doScanner();
        this.rpcEntityMap = new HashMap<>();
        clazzs.forEach((clazz) -> {
            Field[] fields = clazz.getDeclaredFields();
            Map<String, String> fieldsMap = new HashMap<>();
            for (Field field : fields) {

                String key = field.getName();
                char[] chars = field.getName().toCharArray();
                chars[0] = String.valueOf(chars[0]).toUpperCase().toCharArray()[0];
                String value = String.valueOf(chars);
                Annotation rpcField = field.getAnnotation(RpcField.class);
                if(rpcField != null) {
                    String rpcValue = ((RpcField)rpcField).value();
                    if(!StringUtils.isEmpty(rpcValue)) {
                        value = rpcValue.trim();
                    }
                }
                fieldsMap.put(key, value);
            }
            rpcEntityMap.put(clazz.getName(), fieldsMap);
        });

        this.defaultProfile = DefaultProfile.getProfile(profile.getRegionId(), profile.getAccessKeyId(), profile.getAccessSecret());
        this.client = new DefaultAcsClient(defaultProfile);
    }

    /**
     * 加载请求实体类
     */
    private void doScanner() {
        for (String packageName : SCAN_PACKAGE) {
            doScanner(packageName);
        }
    }

    /**
     * 扫描包下所有的包含@RpcEntity注解的类
     * @param packageName
     */
    private void doScanner(String packageName) {
        ClassLoader classLoader = this.getClass().getClassLoader();
        URL url = classLoader.getResource(packageName.replaceAll("\\.","/"));
        String path = null;
        try {
            path = URLDecoder.decode(url.getFile(), "UTF-8");
            File classDir = new File(path);
            if(classDir.exists() && classDir.listFiles()!=null && classDir.listFiles().length>0){
                for (File file : classDir.listFiles()) {
                    if(file.isDirectory()) {
                        doScanner(packageName + "."  + file.getName());
                    } else {
                        String className = packageName + "." + file.getName().replace(".class","");
                        try {
                            Class clazz = Class.forName(className);
                            if(clazz.isAnnotationPresent(RpcEntity.class))
                                clazzs.add(clazz);
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    public AcsResponse rpc(AcsRequest request) throws ClientException {
        if(request == null)
            return null;
        return this.client.getAcsResponse(request);
    }

    public RpcResponse rpc(String action, MethodType methodType, Object rpcEntity) {
        if(StringUtils.isEmpty(action))
            return null;

        CommonRequest request = new CommonRequest();
        request.setMethod(methodType);
        request.setDomain(defaultRequestParams.getDomain());
        request.setVersion(defaultRequestParams.getVersion());
        request.setAction(action);
        String clazzName = rpcEntity.getClass().getName();
        Map<String, String> entityMap =  rpcEntityMap.get(clazzName);
        if(entityMap == null) return null;
        try {
            for (String field : entityMap.keySet()) {
                char[] chars = field.toCharArray();
                chars[0] = String.valueOf(chars[0]).toUpperCase().toCharArray()[0];
                String methodName = "get" + String.valueOf(chars);
                Object result = rpcEntity.getClass().getMethod(methodName, null).invoke(rpcEntity, null);
                if (result != null)
                    request.putQueryParameter(entityMap.get(field), result.toString());
            }
            CommonResponse response = client.getCommonResponse(request);
            if(response == null)
                return null;
            if(200 == response.getHttpStatus())
                return new RpcResponse(response.getHttpStatus() + "", ResponseResult.SUCCESS, response.getData());
            else
                return new RpcResponse(response.getHttpStatus() + "", ResponseResult.ERROR, response.getData());
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public String rpc(String action, MethodType methodType, Map<String, Object> requestParams) {
        if(StringUtils.isEmpty(action))
            return null;
        DefaultProfile defaultProfile = DefaultProfile.getProfile(profile.getRegionId(), profile.getAccessKeyId(), profile.getAccessSecret());
        IAcsClient client = new DefaultAcsClient(defaultProfile);
        CommonRequest request = new CommonRequest();
        request.setMethod(methodType);
        request.setDomain(defaultRequestParams.getDomain());
        request.setVersion(defaultRequestParams.getVersion());
        request.setAction(action);

        if (requestParams != null && requestParams.size() > 0) {
            requestParams.forEach((k, v) -> {
                if (v != null) {
                    request.putQueryParameter(k, v.toString());
                }
            });
        }
        try {
            CommonResponse response = client.getCommonResponse(request);
            return response == null ? null : response.getData();
        } catch (ClientException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void main(String[] args) {
        try{
            CommonRpc commonRpc = new CommonRpc(
                    new Profile("cn-beijing", "LTAIRon7x0qHIhdy","X9AqFQ526j9bjv2fqcdz8KQ5GGzP3A"),
                    new DefaultRequestParams("live.aliyuncs.com", "2016-11-01"));
            LivePullStreamConfig livePullStreamConfig = new LivePullStreamConfig( "huanghelive.zhongkedongxin.com", "LTAIVvNJzQ3Etp6q","nCu0fyV85yn3jes5lRwqx7Q9qxRhSS","cn-beijing");
            DefaultAcsClient client = new DefaultAcsClient(DefaultProfile.getProfile(livePullStreamConfig.getApiRegionId(), livePullStreamConfig.getAccessKeyId(), livePullStreamConfig.getAccessKeySecret()));
            DeleteLiveAppRecordConfigRequest request = new DeleteLiveAppRecordConfigRequest();
            request.setAppName("test");
            request.setDomainName("huanghelive.zhongkedongxin.com");
            request.setStreamName("test");
            AcsResponse response = client.getAcsResponse(request);
            System.out.println(new Gson().toJson(response));

        }catch (Exception e){

        }

//        commonRpc.doScanner();
//        long start = System.currentTimeMillis();
//
//
//        RpcResponse result = commonRpc.rpc("DeleteLiveAppRecordConfig", MethodType.POST, new RequestWrapper<DeleteLiveAppRecordConfigEntity>() {
//            @Override
//            public DeleteLiveAppRecordConfigEntity wrapper() {
//                DeleteLiveAppRecordConfigEntity entity = new DeleteLiveAppRecordConfigEntity();
//                entity.setDomainName("live.zhongkedongxin.com");
//                entity.setAppName("test");
//                entity.setStreamName("test");
//                return entity;
//            }
//        });
//        System.out.println(result);
//        long end1 = System.currentTimeMillis();
//        System.out.println(end1 - start);
//        Map<String, Object> requestParams = new HashMap<>();
//        requestParams.put("DomainName", "live.zhongkedongxin.com");
//        requestParams.put("AppName", "test");
//        requestParams.put("StreamName", "test2");
//        requestParams.put("OssBucket", "demo-scene-caster-video");
//        requestParams.put("OssEndpoint", "oss-cn-shanghai.aliyuncs.com");
//        requestParams.put("RecordFormat.1.OssObjectPrefix", "live-record/{AppName}/{StreamName}/{EscapedStartTime}_{EscapedEndTime}");
//        requestParams.put("RecordFormat.1.Format", "mp4");
//
//        String result2 = commonRpc.rpc("AddLiveAppRecordConfig", MethodType.POST, requestParams);
//        System.out.println(result2);
//        System.out.println(System.currentTimeMillis() - end1);
    }
}
