package com.liquidnet.service.platform.controller.adam;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.platform.service.impl.adam.dm.processor.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.sql.Connection;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.temporal.ChronoField;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Pattern;

@ApiSupport(order = 90062)
@Api(tags = "DM")
@Slf4j
@Validated
@RestController
@RequestMapping("dm")
public class PlatformDMController {
    @Autowired
    DMUserInformationProcessor dmUserInformationProcessor;
    @Autowired
    DMThirdPartsProcessor dmThirdPartsProcessor;
    @Autowired
    DMRealNameProcessor dmRealNameProcessor;
    @Autowired
    DMUserMemberProcessor dmUserMemberProcessor;
    @Autowired
    DMEntersProcessor dmEntersProcessor;
    @Autowired
    DMAddressesProcessor dmAddressesProcessor;
    @Autowired
    DMTracesInfoProcessor dmTracesInfoProcessor;
    @Autowired
    DMMemberOrderProcessor dmMemberOrderProcessor;
    @Autowired
    DMMemberCodeProcessor dmMemberCodeProcessor;
    @Autowired
    DMCollectionProcessor dmCollectionProcessor;

    @ModelAttribute
    public void accessExecuting(HttpServletRequest request) {
        String alis = request.getHeader("alis");
        LocalDateTime now = LocalDateTime.now();
        int hour = now.get(ChronoField.HOUR_OF_DAY), minute = now.getMinute(), dom = now.get(ChronoField.DAY_OF_MONTH);;
        String lns = "^(" + (dom % 10) + hour % (minute / 10 + 1) + "[A-Z]{2})" + minute / 10 + "[0-9]{1}$";
        log.info("lns:{},alis:{}", lns, alis);
        if (StringUtils.isEmpty(alis) || !Pattern.matches(lns, alis)) {
            throw new LiquidnetServiceException("44444", "非法操作");
        }
        log.info("uri:[{}],Parameter:{}", request.getRequestURI(), request.getParameterMap());
    }

    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "T - user")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", name = "dG", example = "220"),
    })
    @GetMapping(value = {"user"})
    public ResponseDto<Object> dataMigrationForUser(@RequestParam(required = false) Integer dG,
                                                    @RequestParam(required = false) String incrDt,
                                                    @RequestParam(required = false) String flg,
                                                    @RequestParam(required = false) String flu
    ) {
        Connection connection = dmUserInformationProcessor.getConnection();
        log.info("===dG:{},incrDt:{},flg:{},flu:{}", dG, incrDt, flg, flu);
        try {
            if (null != dG) {
                ExecutorService exec = Executors.newFixedThreadPool(dG);
                for (int i = 0; i < dG; i++) {
                    final int k = i;
                    exec.execute(() -> {
                        log.info("==================" + k);
                        dmUserInformationProcessor.dataProcessing(connection, k, dG, null, null, k == 0 ? "1" : "");
                    });
                    try { Thread.sleep(100L); } catch (InterruptedException ignored) {}
                }
                exec.shutdown();
            } else {
                dmUserInformationProcessor.dataProcessing(connection,null, null, incrDt, flg, flu);
            }
        } finally {
            try {
                if (null != connection) connection.close();
            } catch (SQLException ignored) {
            }
        }
        return ResponseDto.success(dG);
    }

    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "T - tpa")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", name = "dG", example = "45"),
    })
    @GetMapping(value = {"tpa"})
    public ResponseDto<Object> dataMigrationForTpa(@RequestParam(required = false) Integer dG,
                                                   @RequestParam(required = false) String incrDt,
                                                   @RequestParam(required = false) String flg,
                                                   @RequestParam(required = false) String flu
    ) {
        Connection connection = dmUserInformationProcessor.getConnection();
        try {
            if (null != dG) {
                ExecutorService exec = Executors.newFixedThreadPool(dG);
                for (int i = 0; i < dG; i++) {
                    final int k = i;
                    exec.execute(() -> {
                        log.info("==================" + k);
                        dmThirdPartsProcessor.dataProcessing(connection, k, dG, null, null, k == 0 ? "1" : "");
                    });
                    try { Thread.sleep(100L); } catch (InterruptedException ignored) {}
                }
                exec.shutdown();
            } else {
                dmThirdPartsProcessor.dataProcessing(connection,null, null, incrDt, flg, flu);
            }
        } finally {
            try {
                if (null != connection) connection.close();
            } catch (SQLException ignored) {
            }
        }
        return ResponseDto.success(dG);
    }

    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "T - real")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", name = "dG", example = "2"),
    })
    @GetMapping(value = {"real"})
    public ResponseDto<Object> dataMigrationForReal(@RequestParam(required = false) Integer dG,
                                                    @RequestParam(required = false) String incrDt,
                                                    @RequestParam(required = false) String flg,
                                                    @RequestParam(required = false) String flu
    ) {
        Connection connection = dmUserInformationProcessor.getConnection();
        try {
            if (null != dG) {
                ExecutorService exec = Executors.newFixedThreadPool(dG);
                for (int i = 0; i < dG; i++) {
                    final int k = i;
                    exec.execute(() -> {
                        log.info("==================" + k);
                        dmRealNameProcessor.dataProcessing(connection, k, dG, null, null, k == 0 ? "1" : "");
                    });
                    try { Thread.sleep(100L); } catch (InterruptedException ignored) {}
                }
                exec.shutdown();
            } else {
                dmRealNameProcessor.dataProcessing(connection, null, null, incrDt, flg, flu);
            }
        } finally {
            try {
                if (null != connection) connection.close();
            } catch (SQLException ignored) {
            }
        }
        return ResponseDto.success(dG);
    }

    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "T - collect")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", name = "dG", example = "15"),
    })
    @GetMapping(value = {"collect"})
    public ResponseDto<Object> dataMigrationForCollect(@RequestParam(required = false) Integer dG,
                                                       @RequestParam(required = false) String incrDt,
                                                       @RequestParam(required = false) String flg,
                                                       @RequestParam(required = false) String flu
    ) {
        Connection connection = dmUserInformationProcessor.getConnection();
        try {
            if (null != dG) {
                ExecutorService exec = Executors.newFixedThreadPool(dG);
                for (int i = 0; i < dG; i++) {
                    final int k = i;
                    exec.execute(() -> {
                        log.info("==================" + k);
                        dmCollectionProcessor.dataProcessing(connection, k, dG, null, null, k == 0 ? "1" : "");
                    });
                    try { Thread.sleep(100L); } catch (InterruptedException ignored) {}
                }
                exec.shutdown();
            } else {
                dmCollectionProcessor.dataProcessing(connection, null, null, incrDt, flg, flu);
            }
        } finally {
            try {
                if (null != connection) connection.close();
            } catch (SQLException ignored) {
            }
        }
        return ResponseDto.success(dG);
    }

    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "T - enters")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", name = "dG", example = "93"),
    })
    @GetMapping(value = {"enters"})
    public ResponseDto<Object> dataMigrationForEnters(@RequestParam(required = false) Integer dG,
                                                      @RequestParam(required = false) String incrDt,
                                                      @RequestParam(required = false) String flg,
                                                      @RequestParam(required = false) String flu
    ) {
        Connection connection = dmUserInformationProcessor.getConnection();
        try {
            if (null != dG) {
                ExecutorService exec = Executors.newFixedThreadPool(dG);
                for (int i = 0; i < dG; i++) {
                    final int k = i;
                    exec.execute(() -> {
                        log.info("==================" + k);
                        dmEntersProcessor.dataProcessing(connection, k, dG, null, null, k == 0 ? "1" : "");
                    });
                    try { Thread.sleep(100L); } catch (InterruptedException ignored) {}
                }
                exec.shutdown();
            } else {
                dmEntersProcessor.dataProcessing(connection, null, null, incrDt, flg, flu);
            }
        } finally {
            try {
                if (null != connection) connection.close();
            } catch (SQLException ignored) {
            }
        }
        return ResponseDto.success(dG);
    }

    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "T - addr")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", name = "dG", example = "27"),
    })
    @GetMapping(value = {"addr"})
    public ResponseDto<Object> dataMigrationForAddr(@RequestParam(required = false) Integer dG,
                                                    @RequestParam(required = false) String incrDt,
                                                    @RequestParam(required = false) String flg,
                                                    @RequestParam(required = false) String flu
    ) {
        Connection connection = dmUserInformationProcessor.getConnection();
        try {
            if (null != dG) {
                ExecutorService exec = Executors.newFixedThreadPool(dG);
                for (int i = 0; i < dG; i++) {
                    final int k = i;
                    exec.execute(() -> {
                        log.info("==================" + k);
                        dmAddressesProcessor.dataProcessing(connection, k, dG, null, null, k == 0 ? "1" : "");
                    });
                    try { Thread.sleep(100L); } catch (InterruptedException ignored) {}
                }
                exec.shutdown();
            } else {
                dmAddressesProcessor.dataProcessing(connection, null, null, incrDt, flg, flu);
            }
        } finally {
            try {
                if (null != connection) connection.close();
            } catch (SQLException ignored) {
            }
        }
        return ResponseDto.success(dG);
    }

    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "T - vip")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", name = "dG", example = "2"),
    })
    @GetMapping(value = {"vip"})
    public ResponseDto<Object> dataMigrationForVip(@RequestParam(required = false) Integer dG,
                                                   @RequestParam(required = false) String incrDt,
                                                   @RequestParam(required = false) String flg,
                                                   @RequestParam(required = false) String flu
    ) {
        Connection connection = dmUserInformationProcessor.getConnection();
        try {
            if (null != dG) {
                ExecutorService exec = Executors.newFixedThreadPool(dG);
                for (int i = 0; i < dG; i++) {
                    final int k = i;
                    exec.execute(() -> {
                        log.info("==================" + k);
                        dmUserMemberProcessor.dataProcessing(connection, k, dG, null, null, k == 0 ? "1" : "");
                    });
                    try { Thread.sleep(100L); } catch (InterruptedException ignored) {}
                }
                exec.shutdown();
            } else {
                dmUserMemberProcessor.dataProcessing(connection, null, null, incrDt, flg, flu);
            }
        } finally {
            try {
                if (null != connection) connection.close();
            } catch (SQLException ignored) {
            }
        }
        return ResponseDto.success(dG);
    }

    @ApiOperationSupport(order = 8)
    @ApiOperation(value = "morder")
    @GetMapping(value = {"morder"})
    public ResponseDto<Object> dataMigrationForMOrder(@RequestParam(required = false) Integer dG,
                                                      @RequestParam(required = false) String incrDt,
                                                      @RequestParam(required = false) String flg,
                                                      @RequestParam(required = false) String flu
    ) {
        Connection connection = dmUserInformationProcessor.getConnection();
        try {
            dmMemberOrderProcessor.dataProcessing(connection, null, null, incrDt, flg, flu);
        } finally {
            try {
                if (null != connection) connection.close();
            } catch (SQLException ignored) {
            }
        }
        return ResponseDto.success(dG);
    }

    @ApiOperationSupport(order = 9)
    @ApiOperation(value = "mcode")
    @GetMapping(value = {"mcode"})
    public ResponseDto<Object> dataMigrationForMCode(@RequestParam(required = false) Integer dG,
                                                     @RequestParam(required = false) String incrDt,
                                                     @RequestParam(required = false) String flg,
                                                     @RequestParam(required = false) String flu
    ) {
        Connection connection = dmUserInformationProcessor.getConnection();
        try {
            dmMemberCodeProcessor.dataProcessing(connection, null, null, incrDt, flg, flu);
        } finally {
            try {
                if (null != connection) connection.close();
            } catch (SQLException ignored) {
            }
        }
        return ResponseDto.success(dG);
    }

    @ApiOperationSupport(order = 10)
    @ApiOperation(value = "traces")
    @GetMapping(value = {"traces"})
    public ResponseDto<Object> dataMigrationForTraces(@RequestParam(required = false) Integer dG,
                                                      @RequestParam(required = false) String incrDt,
                                                      @RequestParam(required = false) String flg,
                                                      @RequestParam(required = false) String flu
    ) {
        Connection connection = dmUserInformationProcessor.getConnection();
        try {
            dmTracesInfoProcessor.dataProcessing(connection, null, null, incrDt, flg, flu);
        } finally {
            try {
                if (null != connection) connection.close();
            } catch (SQLException ignored) {
            }
        }
        return ResponseDto.success(dG);
    }
}
