package com.its.bis.webapp.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.its.app.utils.Ping;
import com.its.bis.config.ApplicationConfig;
import com.its.bis.webapp.service.FileService;
import com.its.bis.webapp.vo.FileInfoVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@RequiredArgsConstructor
@Controller
public class WebAppCommonController {

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

    @RequestMapping({"/", "/index"})
    public String index(Model model, HttpServletRequest request) {

        String result = "system";
        model.addAttribute("ServerConfig", this.applicationConfig);
        model.addAttribute("ServerTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        return result;
    }

    @RequestMapping("/log")
    public String logFiles(Model model, HttpServletRequest request) {
        String result = "log";
        List<FileInfoVo> info = this.fileService.getLogFiles();

        //JSON 형식으로 바꿔주기
        ObjectMapper mapper = new ObjectMapper();
        String jsonList="";
        try {
            jsonList = mapper.writeValueAsString(info);
        }
        catch (IOException e) {
            log.error("WebAppController.logFiles: Exception: {}", e.toString());
        }

        model.addAttribute("ServerConfig", this.applicationConfig);
        model.addAttribute("fileList",jsonList);
        model.addAttribute("ServerTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        return result;
    }

    @RequestMapping("/login")
    public String login(Model model) {
        String result = "login";
        model.addAttribute("ServerConfig", this.applicationConfig);
        model.addAttribute("ServerTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        return result;
    }

    @GetMapping("/logout")
    public void logout() {
    }

    @RequestMapping("/getServerDate")
    @ResponseBody
    public Map<String,Object> getServerDate() {
        Map<String,Object> map = new HashMap<>();
        map.put("serverDate", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        return map;
    }

    @RequestMapping(value = "/getFileView",method = {RequestMethod.POST},produces = {"application/json"})
    @ResponseBody
    public String getFileView(@RequestParam("fileName") String fileName, @RequestParam("filePath") String filePath, HttpServletRequest request) {
        return this.fileService.getView(request, fileName, filePath);
    }

    @RequestMapping("/getFileDownload")
    public ResponseEntity<Resource> getFileDownload(@RequestParam("fileName") String fileName , @RequestParam("filePath") String filePath
            , HttpSession session
            , HttpServletRequest req
            , HttpServletResponse res
            , ModelAndView mav) throws UnsupportedEncodingException {

        return this.fileService.fileDownload(fileName,filePath);
    }

    @RequestMapping(value = ("/getFileDelete"))
    @ResponseBody
    public List<FileInfoVo> getFileDelete(@RequestParam("fileName") String fileName, @RequestParam("filePath") String filePath) {
        //파일 지우기
        this.fileService.fileDelete(fileName,filePath);
        //파일 리스트 가져오기
        List<FileInfoVo> fileArr =fileService.getLogFiles();
        return fileArr;
    }


    @RequestMapping(value = ("/getPing"))
    @ResponseBody
    public String getPing(@RequestParam("ipAddr") String ipAddr) {
        //log.info("getPing: {}", ipAddr);
        String result =  ping(ipAddr);
        //log.info("getPing: {} ==> {}", ipAddr, result);
        return result;
    }

    public String ping(String ipAddr) {
        String result = "";
        long startTm = System.nanoTime();
        long endTm = System.nanoTime();
        try {
            boolean isReachable = Ping.isReachable(ipAddr, 5);
            endTm = System.nanoTime();
            if (isReachable ) {
                result = ipAddr + " is alive. " + Long.toString((endTm - startTm) / 1000000) + " ms.";
            }
            else {
                result = ipAddr + " is not alive. time out: " + Long.toString((endTm - startTm) / 1000000) + " ms.";
            }
        }
        catch (Exception e) {
            result = ipAddr + " error. " + Long.toString((endTm - startTm) / 1000000) + " ms. Exception: " + e.toString();
        }

        return result;
    }

}
