package com.eactive.eai.rms.ext.djb.apistatus;
import java.util.List;

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import com.eactive.eai.data.jpa.BaseRepository;
import com.eactive.eai.rms.data.entity.onl.djb.apistatus.ApiStatus;
import com.eactive.eai.rms.data.entity.onl.djb.apistatus.ApiStatusEvent;

public interface ApiStatusRepository extends BaseRepository<ApiStatus, String> {

	/**
	 * API 상태 판단.  정상(N), 점검(C), 지연(D), 장애(E)
	 * 
	 * 1. 정상/지연/장애 -> 점검중 : CONTROL_START
	 * 2. 점검 -> 점검X : CONTROL_END
	 * 3. 정상/지연 -> 장애 : ERROR_START
	 * 4. 장애 -> 장애X : ERROR_END
	 * 5. 정상 -> 지연 : DELAY_START
	 * 6. 지연 -> 지연X : DELAY_END
	 * 7. 기타 : STAY
	 */
	@Query(nativeQuery = true, value =
	    " SELECT EAISVCNAME"
	  + "      , (SELECT EAISVCDESC FROM TSEAIHE01 WHERE A.EAISVCNAME = EAISVCNAME) AS EAISVCDESC" 
	  + "      , PREV_STATUS_CODE "
	  + "      , EVENT"
	  + " FROM ("
	  + "   SELECT EAISVCNAME"
	  + "        , STATUS_CODE AS PREV_STATUS_CODE "
	  + "        , CASE WHEN STATUS_CODE != 'C' AND CTRL_YN = 'Y'  THEN 'CONTROL_START'"
	  + "               WHEN STATUS_CODE  = 'C' AND CTRL_YN = 'N'  THEN 'CONTROL_END'"
	  + "               WHEN STATUS_CODE IN ('N','D') AND ERR_YN = 'Y' THEN 'ERROR_START'"
	  + "               WHEN STATUS_CODE  = 'E' AND ERR_YN = 'N'  THEN 'ERROR_END'"
	  + "               WHEN STATUS_CODE  = 'N' AND DELAY_YN = 'Y' THEN 'DELAY_START'"
	  + "               WHEN STATUS_CODE  = 'D' AND DELAY_YN = 'N' THEN 'DELAY_END'"
	  + "          ELSE 'STAY' END AS EVENT"
	  + "   FROM ("
	  + "     SELECT A.EAISVCNAME"
	  + "          , NVL(B.STATUS_CODE, 'N') AS STATUS_CODE"
	  + "          , NVL(( SELECT MAX('Y') FROM EMSAPP.DJB_APISTATUS_INCIDENT_API X"
	  + "                   WHERE EXISTS (SELECT 1 FROM EMSAPP.DJB_APISTATUS_INCIDENT Y WHERE X.INCIDENT_ID = Y.INCIDENT_ID "
	  + "        	                       AND SYSTIMESTAMP BETWEEN STARTED_AT AND END_AT) "
	  + "                     AND A.EAISVCNAME = X.API_ID),'N') AS CTRL_YN "
	  + "          , (SELECT CASE WHEN TOTAL = 0 THEN 'X'"
	  + "                         WHEN (TOTAL - SUCCESS) * 100 / TOTAL > :errorRate THEN 'Y'"
	  + "                    ELSE 'N' END"
	  + "               FROM (SELECT NVL(SUM(SUCCESS_CNT + TIMEOUT_CNT + SYSTEM_ERR_CNT + BIZ_ERR_CNT),0) AS TOTAL"
	  + "                          , SUM(SUCCESS_CNT) AS SUCCESS"
	  + "                       FROM API_STATS_MINUTE"
	  + "                      WHERE A.EAISVCNAME = API_NAME"
	  + "                        AND TO_CHAR(STAT_TIME,'YYYYMMDDHH24MI')"
	  + "                            BETWEEN TO_CHAR(SYSDATE - NUMTODSINTERVAL(:errorRangeMinute,'MINUTE'),'YYYYMMDDHH24MI')"
	  + "                                AND TO_CHAR(SYSDATE,'YYYYMMDDHH24MI'))) AS ERR_YN"
	  + "          , (SELECT CASE WHEN TOTAL = 0 THEN 'X'"
	  + "                        WHEN RESP_SUM / TOTAL > :delayAvgRespTime THEN 'Y'"
	  + "                   ELSE 'N' END"
	  + "               FROM (SELECT NVL(SUM(SUCCESS_CNT + TIMEOUT_CNT + SYSTEM_ERR_CNT + BIZ_ERR_CNT),0) AS TOTAL"
	  + "                          , SUM(SUCCESS_CNT) AS SUCCESS"
	  + "                          , SUM((SUCCESS_CNT + TIMEOUT_CNT + SYSTEM_ERR_CNT + BIZ_ERR_CNT) * AVG_RESP_TIME) AS RESP_SUM"
	  + "                       FROM API_STATS_MINUTE"
	  + "                      WHERE A.EAISVCNAME = API_NAME"
	  + "                        AND TO_CHAR(STAT_TIME,'YYYYMMDDHH24MI')"
	  + "                            BETWEEN TO_CHAR(SYSDATE - NUMTODSINTERVAL(:delayRangeMinute,'MINUTE'),'YYYYMMDDHH24MI')"
	  + "                                AND TO_CHAR(SYSDATE,'YYYYMMDDHH24MI'))) AS DELAY_YN"
	  + "       FROM TSEAIHE01 A LEFT OUTER JOIN API_STATUS B ON A.EAISVCNAME = B.EAISVCNAME"
	  + "   )"
	  + " ) A WHERE EVENT != 'STAY'")
	List<ApiStatusEvent> findApiStatusEvents(
			@Param("errorRate")        int errorRate,
			@Param("errorRangeMinute") int errorRangeMinute,
			@Param("delayRangeMinute") int delayRangeMinute,
			@Param("delayAvgRespTime") int delayAvgRespTime
	);
}