package com.lightinit.hsdatagateway.modules.foreign.exe;

import com.alibaba.fastjson.JSON;
import com.lightinit.hsdatagateway.modules.foreign.model.RequestDto;
import com.lightinit.hsdatagateway.modules.foreign.model.ResponseModel;
import com.lightinit.hsdatagateway.modules.foreign.service.BusinessExecuteService;
import com.lightinit.hsdatagateway.modules.foreign.service.PayConfirmService;
import com.lightinit.hsdatagateway.modules.foreign.service.PayVerifyService;
import com.lightinit.hsdatagateway.modules.foreign.service.PermissionVerifyService;
import com.lightinit.hsdatagateway.modules.gateway.entity.BizRoute;
import com.lightinit.hsdatagateway.modules.gateway.entity.CallLog;
import com.lightinit.hsdatagateway.modules.gateway.service.BizRouteService;
import com.lightinit.hsdatagateway.modules.gateway.service.CallLogService;
import com.lightinit.hsdatagateway.modules.foreign.model.RequestDto;
import com.lightinit.hsdatagateway.modules.foreign.model.ResponseModel;
import com.lightinit.hsdatagateway.modules.foreign.service.BusinessExecuteService;
import com.lightinit.hsdatagateway.modules.foreign.service.PayConfirmService;
import com.lightinit.hsdatagateway.modules.foreign.service.PayVerifyService;
import com.lightinit.hsdatagateway.modules.foreign.service.PermissionVerifyService;
import com.lightinit.hsdatagateway.modules.gateway.entity.CallLog;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;

/**
 * @Author: yangrui
 * @Date: 2019/3/5 12:39
 */
@Service
@Slf4j
public class ServiceExe {
    @Qualifier("BusinessExecutor")
    @Autowired
    ExecutorService executorService;
    @Autowired
    PermissionVerifyService permissionVerifyService;
    @Autowired
    PayConfirmService payConfirmService;
    @Autowired
    PayVerifyService payVerifyService;
    @Autowired
    BusinessExecuteService businessExecuteService;
    @Autowired
    CallLogService callLogService;
    @Autowired
    BizRouteService bizRouteService;

    public ResponseModel execute(RequestDto requestDto) {
        RequestDto result = CompletableFuture.supplyAsync(() -> permissionVerifyService.setRequestDto(requestDto).call(), executorService)
                .thenApplyAsync(requestDto1 -> payVerifyService.setRequestDto(requestDto1).call(), executorService)
                .thenApplyAsync(requestDto1 -> businessExecuteService.setRequestDto(requestDto1).call(), executorService)
                .thenApplyAsync(requestDto1 -> payConfirmService.setRequestDto(requestDto1).call(), executorService)
                .whenCompleteAsync((requestDto1, t) ->
                        executorService.submit(() -> {
                            CallLog callLog = new CallLog();
                            try {
                                callLog.setCreatedBy(requestDto.getUserId());
                                callLog.setCreatedAt(new Date());
                                callLog.setCallTime(new Date());
                                callLog.setUserId(requestDto.getUserId());
                                callLog.setAppId(requestDto.getAppId());
                                if (Objects.isNull(t)) {
                                    callLog.setRouteId(requestDto1.getRouteId());
                                    callLog.setCallResult(String.valueOf(requestDto1.getResponseModel().getCode()));
                                    ResponseModel responseModel = requestDto1.getResponseModel();
                                    if (Objects.nonNull(responseModel)){
                                        callLog.setRemark(StringUtils.join(responseModel.getReasonPhrase(), "请求发送时间(ms)",requestDto1.getTime()));
                                    }
                                } else {
                                    //获取路由
                                    BizRoute byContextPath = bizRouteService.getByContextPath(requestDto.getPath());
                                    callLog.setRouteId(byContextPath.getRouteId());
                                    callLog.setCallResult("500");
                                    callLog.setRemark(t.getMessage());
                                }
                                callLogService.save(callLog);
                            } catch (Exception e) {
                                log.warn("callLog return result modify fail, callLog is {}", JSON.toJSONString(callLog),e);
                            }
                        })
                )
                .join();
        return result.getResponseModel();
    }

//    private static ExecutorService executorService1 = Executors.newSingleThreadExecutor();
//
//
//    public static void main(String[] args) {
//        String s = get();
//        System.out.println("final===" + s);
//    }
//
//
//    private static String get() {
//        Integer two = CompletableFuture.supplyAsync(() -> 10 / 2)
////                .whenCompleteAsync((s, t) -> {
////                    System.out.println(t.getMessage());
////                })
//                .thenApplyAsync(i -> {
//                    System.out.println("two");
//                    i++;
//                    return i;
//                }).whenCompleteAsync((s, t) -> {
//
//                    Runnable wait = new Runnable() {
//                        @Override
//                        public void run() {
//                            try {
//                                Thread.sleep(5000);
//                                System.out.println("thread test");
//                            } catch (InterruptedException e) {
//                                e.printStackTrace();
//                            }
//                        }
//                    };
//                    executorService1.execute(wait);
//
//                    if (Objects.nonNull(t)) {
//                        System.out.println(t.getMessage());
//                    } else {
//                        System.out.println("test when" + s);
//                    }
//                })
//                .join();
//        return two.toString();
//    }

}
