package com.its.vds.stat.server.controller;

import com.its.vds.stat.server.config.ApplicationConfig;
import com.its.vds.stat.server.dto.StatResultDto;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.ArrayDeque;
import java.util.Date;
import java.util.Deque;

@RestController
@RequiredArgsConstructor
@RequestMapping("/info")
public class VdsStatServerRestController {

    private final ApplicationConfig config;

    private final Deque<StatResultDto> min05Hs = new ArrayDeque<>();
    private final Deque<StatResultDto> min15Hs = new ArrayDeque<>();
    private final Deque<StatResultDto> hourHs = new ArrayDeque<>();
    private final Deque<StatResultDto> dayHs = new ArrayDeque<>();
    private final Deque<StatResultDto> monthHs = new ArrayDeque<>();
    private final Deque<StatResultDto> yearHs = new ArrayDeque<>();

    private void makeStateResult(Deque<StatResultDto> history, String currDt, String statDt, String fromDt, String toDt, int result) {
        final int MAX_HISTORY = 144;
        try {
            StatResultDto record = new StatResultDto(currDt, statDt, fromDt, toDt, result);
            if (history.size() >= MAX_HISTORY) {
                history.removeFirst();
            }
            history.addLast(record);
        }
        catch (Exception e) {
            // no logging
        }
    }

    public void addMin05Hs(String currDt, String statDt, String fromDt, String toDt, int result) {
        makeStateResult(this.min05Hs, currDt, statDt, fromDt, toDt, result);
    }
    public void addMin15Hs(String currDt, String statDt, String fromDt, String toDt, int result) {
        makeStateResult(this.min15Hs, currDt, statDt, fromDt, toDt, result);
    }
    public void addHourHs(String currDt, String statDt, String fromDt, String toDt, int result) {
        makeStateResult(this.hourHs, currDt, statDt, fromDt, toDt, result);
    }
    public void addDayHs(String currDt, String statDt, String fromDt, String toDt, int result) {
        makeStateResult(this.dayHs, currDt, statDt, fromDt, toDt, result);
    }
    public void addMonthHs(String currDt, String statDt, String fromDt, String toDt, int result) {
        makeStateResult(this.monthHs, currDt, statDt, fromDt, toDt, result);
    }
    public void addYearHs(String currDt, String statDt, String fromDt, String toDt, int result) {
        makeStateResult(this.yearHs, currDt, statDt, fromDt, toDt, result);
    }


    private String now() {
        Date today = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(today);
    }

    private String displayHistory(Deque<StatResultDto> history, String statDesc) {
        final String heading = "---------------------------------------------------------------------------------------------------------------------";
        String sep = System.lineSeparator();

        StringBuilder sb = new StringBuilder();
        sb.append(sep);
        sb.append(heading).append(sep);
        sb.append("VDS Statistics Server Running Information").append(sep);
        sb.append(heading).append(sep);
        sb.append(String.format("Process: %s(%s), Booting: %s, Now: %s, [%s Statistics]",
                this.config.getProcessId(), this.config.getProcessName(), this.config.getBootingTime(), now(), statDesc)).append(sep);
        sb.append(heading).append(sep);

        sb.append(sep);
        sb.append(heading).append(sep);
        sb.append("SEQ exeDt           statDt          fromDt          toDt            result").append(sep);
        sb.append(heading).append(sep);

        int ii = 1;
        for (StatResultDto record : history) {
            sb.append(String.format("%3d %-14.14s  %-14.14s  %-14.14s  %-14.14s  %d",
                    ii++,
                    record.getCurrDt(),
                    record.getStatDt(),
                    record.getFromDt(),
                    record.getToDt(),
                    record.getResult())).append(sep);
        }
        sb.append(heading).append(sep);
        return sb.toString();
    }

    @GetMapping(value = "/05min", produces = {"application/json; charset=utf8"})
    public String infoMin05() {
        return displayHistory(this.min05Hs, "05 Min");
    }

    @GetMapping(value = "/15min", produces = {"application/json; charset=utf8"})
    public String infoMin15() {
        return displayHistory(this.min15Hs, "15 Min");
    }

    @GetMapping(value = "/hour", produces = {"application/json; charset=utf8"})
    public String infoHour() {
        return displayHistory(this.hourHs, "Hour");
    }

    @GetMapping(value = "/day", produces = {"application/json; charset=utf8"})
    public String infoDay() {
        return displayHistory(this.dayHs, "Day");
    }

    @GetMapping(value = "/month", produces = {"application/json; charset=utf8"})
    public String infoMonth() {
        return displayHistory(this.monthHs, "Month");
    }

    @GetMapping(value = "/year", produces = {"application/json; charset=utf8"})
    public String infoYear() {
        return displayHistory(this.yearHs, "Year");
    }

}
