package com.its.dsrc.webapp.controller;

import com.its.dsrc.config.ApplicationConfig;
import com.its.dsrc.entity.TbRseCtlr;
import com.its.dsrc.global.AppRepository;
import com.its.dsrc.vo.NET;
import com.its.dsrc.webapp.service.FileService;
import com.its.dsrc.xnettcp.dsrc.handler.DsrcAsn1ServerIdleStateConnectionHandler;
import com.its.dsrc.xnettcp.dsrc.handler.DsrcAsn1ServerIdleStatePacketHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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;

@Slf4j
@RequiredArgsConstructor
@Controller
public class WebAppController {

    private final ResourceLoader resourceLoader;
    private final ApplicationConfig applicationConfig;
    private final FileService fileService;

    @RequestMapping(value = {"/controller"})
    public String controller(Model model, HttpServletRequest request) {
        String result = "controller";
        SortedMap<Integer, TbRseCtlr> ctlrMap = new TreeMap<>();
        for (Map.Entry<String, TbRseCtlr> e : AppRepository.getInstance().getCtlrMap().entrySet()) {
            TbRseCtlr obj = e.getValue();
            if (obj.getNetState() == NET.CLOSED) {
                if (obj.getChannel() != null || obj.getLogin() != null) {
                    obj.setNetState(NET.LOGINED);
                }
            }
            ctlrMap.put(Integer.valueOf(obj.getID()), obj);
        }
        model.addAttribute("ServerConfig", this.applicationConfig);
        //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, TbRseCtlr> getControllerInfo() {
        ConcurrentHashMap<Integer, TbRseCtlr> ctlrMap = new ConcurrentHashMap<>();
        for (Map.Entry<String, TbRseCtlr> e : AppRepository.getInstance().getCtlrMap().entrySet()) {
            TbRseCtlr obj = e.getValue();
            ctlrMap.put(Integer.valueOf(obj.getID()), obj);
        }
        return ctlrMap;
    }

    @RequestMapping(value = ("/disconnectController"))
    @ResponseBody
    public String disconnectController(@RequestParam("id") String id) {
        String result = "제어기와의 통신 연결을 종료 하였습니다.";
        TbRseCtlr ctlr = AppRepository.getInstance().getCtlrMap().get(id);
        if (ctlr != null && ctlr.getNetState() > NET.CLOSED && ctlr.getChannel() != null) {
            if (ctlr.getNetState() == NET.LOGIN_REQ) {
                DsrcAsn1ServerIdleStateConnectionHandler.disconnectChannel(ctlr.getChannel());
            }
            else {
                DsrcAsn1ServerIdleStatePacketHandler.disconnectChannel(ctlr, 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, TbRseCtlr> e : AppRepository.getInstance().getCtlrMap().entrySet()) {
            TbRseCtlr ctlr = e.getValue();
            //if (ctlr != null && ctlr.getNetState() > NET.CLOSED && ctlr.getChannel() != null) {
            if (ctlr != null && ctlr.getChannel() != null) {
                if (ctlr.getNetState() == NET.LOGIN_REQ) {
                    DsrcAsn1ServerIdleStateConnectionHandler.disconnectChannel(ctlr.getChannel());
                }
                else {
                    DsrcAsn1ServerIdleStatePacketHandler.disconnectChannel(ctlr, 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 = "통신 접속횟수를 초기화 하였습니다.";
        TbRseCtlr 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, TbRseCtlr> e : AppRepository.getInstance().getCtlrMap().entrySet()) {
            TbRseCtlr ctlr = e.getValue();
            ctlr.resetConnectCount();
        }
        return result;
    }

    @RequestMapping(value = ("/resetController"))
    @ResponseBody
    public String resetController(@RequestParam("id") String id) {
        String result = "제어기를 리셋 하였습니다.";
        TbRseCtlr 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, TbRseCtlr> e : AppRepository.getInstance().getCtlrMap().entrySet()) {
            TbRseCtlr ctlr = e.getValue();
            if (ctlr != null && ctlr.getNetState() > NET.CLOSED && ctlr.getChannel() != null) {
                if (ctlr.getNetState() == NET.LOGIN_REQ) {
                    DsrcAsn1ServerIdleStateConnectionHandler.disconnectChannel(ctlr.getChannel());
                }
                else {
                    DsrcAsn1ServerIdleStatePacketHandler.disconnectChannel(ctlr, ctlr.getChannel());
                }
            }
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return result;
    }

}
