package com.its.pis.webapp.controller;

import com.its.pis.config.ProcessConfig;
import com.its.pis.domain.NET;
import com.its.pis.entity.TbVdsCtlr;
import com.its.pis.global.AppRepository;
import com.its.pis.webapp.service.FileService;
import com.its.pis.xnettcp.vds.handler.VdsTcpClientIdleHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;

@RequiredArgsConstructor
@Slf4j
@Controller
public class WebAppController {

    private final ResourceLoader resourceLoader;
    private final ProcessConfig processConfig;
    private final FileService fileService;

    @RequestMapping(value = {"/controller"})
    public String controller(Model model, HttpServletRequest request) {
        String result = "controller";
        SortedMap<Integer, TbVdsCtlr> ctlrMap = new TreeMap<>();
        for (Map.Entry<String, TbVdsCtlr> e : AppRepository.getInstance().getCtlrMap().entrySet()) {
            TbVdsCtlr obj = e.getValue();
            if (StringUtils.equals("N", obj.getDEL_YN()) && StringUtils.equals("Y", obj.getVALD_YN())) {
                ctlrMap.put(Integer.valueOf(obj.getVDS_CTLR_NMBR()), obj);
            }
        }
        model.addAttribute("ServerConfig", this.processConfig);
        //model.addAttribute("list", AppRepository.getInstance().getCtlrMap().entrySet());
        model.addAttribute("list", ctlrMap);
        model.addAttribute("ServerTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        return result;
    }

    @RequestMapping("/getControllerInfo")
    @ResponseBody
    public ConcurrentHashMap<Integer, TbVdsCtlr> getControllerInfo() {
        //List<Map<String, voVdsCtlr>> infoList = new ArrayList<>();
        ConcurrentHashMap<Integer, TbVdsCtlr> ctlrMap = new ConcurrentHashMap<>();
        for (Map.Entry<String, TbVdsCtlr> e : AppRepository.getInstance().getCtlrMap().entrySet()) {
            TbVdsCtlr obj = e.getValue();
            if (StringUtils.equals("N", obj.getDEL_YN()) && StringUtils.equals("Y", obj.getVALD_YN())) {
                ctlrMap.put(Integer.valueOf(obj.getVDS_CTLR_NMBR()), obj);
            }
        }
        return ctlrMap;
/*
        for (Map.Entry<String, voVdsCtlr> obj : AppRepository.getInstance().getCtlrMap().entrySet()) {
            log.info(obj.toString());
        }
        return AppRepository.getInstance().getCtlrMap();*/
    }

    @RequestMapping(value = ("/disconnectController"))
    @ResponseBody
    public String disconnectController(@RequestParam("id") String id) {
        String result = "제어기와의 통신 연결을 종료 하였습니다.";
        TbVdsCtlr ctlr = AppRepository.getInstance().getCtlrMap().get(id);
        if (ctlr != null && ctlr.getNetState() > NET.CLOSED && ctlr.getChannel() != null) {
            VdsTcpClientIdleHandler.disconnectChannel(ctlr.getChannel());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        else {
            result = "제어기는 현재 연결되어 있지 않습니다.";
        }
        return result;
    }

    @RequestMapping(value = ("/allDisconnectController"))
    @ResponseBody
    public String allDisconnectController() {
        String result = "통신 연결 중인 제어기와의 통신 연결을 종료 하였습니다.";
        for (Map.Entry<String, TbVdsCtlr> e : AppRepository.getInstance().getCtlrMap().entrySet()) {
            TbVdsCtlr ctlr = e.getValue();
            if (ctlr != null && ctlr.getNetState() > NET.CLOSED && ctlr.getChannel() != null) {
                VdsTcpClientIdleHandler.disconnectChannel(ctlr.getChannel());
            }
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return result;
    }

    @RequestMapping(value = ("/resetConnCount"))
    @ResponseBody
    public String resetConnCount(@RequestParam("id") String id) {
        String result = "통신 접속횟수를 초기화 하였습니다.";
        TbVdsCtlr ctlr = AppRepository.getInstance().getCtlrMap().get(id);
        if (ctlr != null) {
            ctlr.resetConnectCount();
        }
        return result;
    }

    @RequestMapping(value = ("/allResetConnCount"))
    @ResponseBody
    public String allResetConnCount() {
        String result = "모든 제어기의 통신 접속횟수를 초기화 하였습니다.";
        for (Map.Entry<String, TbVdsCtlr> e : AppRepository.getInstance().getCtlrMap().entrySet()) {
            TbVdsCtlr ctlr = e.getValue();
            ctlr.resetConnectCount();
        }
        return result;
    }

    @RequestMapping(value = ("/resetController"))
    @ResponseBody
    public String resetController(@RequestParam("id") String id) {
        String result = "제어기를 리셋 하였습니다.";
        TbVdsCtlr ctlr = AppRepository.getInstance().getCtlrMap().get(id);
        if (ctlr != null && ctlr.getNetState() > NET.CLOSED && ctlr.getChannel() != null) {
            /*TcpServerIdleStateHandler.disconnectChannel(ctlr.getChannel());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }*/
        }
        else {
            result = "제어기는 현재 연결되어 있지 않습니다.";
        }
        return result;
    }

    @RequestMapping(value = ("/allResetController"))
    @ResponseBody
    public String allResetController(@RequestParam("id") String id) {
        String result = "통신 연결 중인 제어기를 리셋 하였습니다.";
        for (Map.Entry<String, TbVdsCtlr> e : AppRepository.getInstance().getCtlrMap().entrySet()) {
            TbVdsCtlr ctlr = e.getValue();
            if (ctlr != null && ctlr.getNetState() > NET.CLOSED && ctlr.getChannel() != null) {
                VdsTcpClientIdleHandler.disconnectChannel(ctlr.getChannel());
            }
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return result;
    }

}
