package app.monitor.alert;

import app.monitor.AlertConfig;
import core.framework.log.Severity;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

/**
 * @author neo
 */
class AlertMatcherTest {
    @Test
    void matchAppAndErrorCode() {
        var matcher = new AlertMatcher(List.of(
                matcher(List.of("website", "backoffice"), List.of("PATH_NOT_FOUND"), null, List.of()),
                matcher(List.of("frontend-website"), List.of("API_ERROR_401", "FORBIDDEN"), null, List.of()),
                matcher(List.of(), List.of("VALIDATION_ERROR"), null, List.of()), // match all apps if apps is empty
                matcher(List.of(), List.of("UNAUTHORIZED"), null, List.of())
        ));

        assertThat(matcher.matches(alert("website", "PATH_NOT_FOUND", Severity.WARN, "trace"))).isTrue();
        assertThat(matcher.matches(alert("frontend-website", "FORBIDDEN", Severity.WARN, "trace"))).isTrue();
        assertThat(matcher.matches(alert("customer-service", "FORBIDDEN", Severity.WARN, "trace"))).isFalse();
        assertThat(matcher.matches(alert("website", "METHOD_NOT_ALLOWED", Severity.WARN, "trace"))).isFalse();
        assertThat(matcher.matches(alert("customer-service", "VALIDATION_ERROR", Severity.WARN, "trace"))).isTrue();
        assertThat(matcher.matches(alert("customer-service", "UNAUTHORIZED", Severity.WARN, "trace"))).isTrue();
    }

    @Test
    void matchesSeverityAndIndex() {
        var matcher = new AlertMatcher(List.of(
                matcher(List.of(), List.of(), Severity.ERROR, List.of("event")),
                matcher(List.of(), List.of(), Severity.WARN, List.of("trace", "stat")),
                matcher(List.of("website"), List.of("PATH_NOT_FOUND"), Severity.ERROR, List.of("trace"))
        ));

        assertThat(matcher.matches(alert("website", "UNAUTHORIZED", Severity.ERROR, "event"))).isTrue();
        assertThat(matcher.matches(alert("customer-service", "UNAUTHORIZED", Severity.ERROR, "event"))).isTrue();
        assertThat(matcher.matches(alert("website", "UNAUTHORIZED", Severity.ERROR, "trace"))).isFalse();
        assertThat(matcher.matches(alert("customer-service", "UNAUTHORIZED", Severity.ERROR, "trace"))).isFalse();

        assertThat(matcher.matches(alert("website", "UNAUTHORIZED", Severity.WARN, "trace"))).isTrue();
        assertThat(matcher.matches(alert("customer-service", "UNAUTHORIZED", Severity.WARN, "trace"))).isTrue();
        assertThat(matcher.matches(alert("website", "UNAUTHORIZED", Severity.WARN, "event"))).isFalse();
        assertThat(matcher.matches(alert("customer-service", "UNAUTHORIZED", Severity.WARN, "event"))).isFalse();

        assertThat(matcher.matches(alert("website", "PATH_NOT_FOUND", Severity.ERROR, "trace"))).isTrue();
        assertThat(matcher.matches(alert("customer-service", "PATH_NOT_FOUND", Severity.ERROR, "trace"))).isFalse();
        assertThat(matcher.matches(alert("website", "UNAUTHORIZED", Severity.ERROR, "trace"))).isFalse();
    }

    @Test
    void matchesExcludeErrorCodes() {
        var rule = new AlertConfig.Matcher();
        rule.excludeErrorCodes = List.of("ERROR_CODE_FOR_OTHER_TEAM");
        var matcher = new AlertMatcher(List.of(rule));

        assertThat(matcher.matches(alert("website", "ERROR_CODE_FOR_OTHER_TEAM", Severity.ERROR, "trace"))).isFalse();
        assertThat(matcher.matches(alert("website", "UNAUTHORIZED", Severity.ERROR, "trace"))).isTrue();
    }

    private AlertConfig.Matcher matcher(List<String> apps, List<String> errorCodes, Severity severity, List<String> indices) {
        var matcher = new AlertConfig.Matcher();
        matcher.apps = apps;
        matcher.errorCodes = errorCodes;
        matcher.severity = severity;
        matcher.indices = indices;
        return matcher;
    }

    private Alert alert(String app, String errorCode, Severity severity, String index) {
        var alert = new Alert();
        alert.app = app;
        alert.errorCode = errorCode;
        alert.severity = severity;
        alert.kibanaIndex = index;
        return alert;
    }
}

@@ -401,24 +401,41 @@
 ackoffice%22),
+ List.of(), null,
  List.of(%22PA
@@ -445,30 +445,24 @@
 NOT_FOUND%22),
- null,
  List.of()),
@@ -506,32 +506,49 @@
 ntend-website%22),
+ List.of(), null,
  List.of(%22API_ER
@@ -570,22 +570,16 @@
 IDDEN%22),
- null,
  List.of
@@ -609,32 +609,49 @@
 tcher(List.of(),
+ List.of(), null,
  List.of(%22VALIDA
@@ -663,22 +663,16 @@
 ERROR%22),
- null,
  List.of
@@ -737,32 +737,49 @@
 tcher(List.of(),
+ List.of(), null,
  List.of(%22UNAUTH
@@ -787,22 +787,16 @@
 RIZED%22),
- null,
  List.of
@@ -1617,32 +1617,39 @@
 t.of(), List.of(
+%22event%22
 ), Severity.ERRO
@@ -1659,23 +1659,27 @@
 List.of(
-%22event%22
+), List.of(
 )),%0A    
@@ -1717,16 +1717,31 @@
 List.of(
+%22trace%22, %22stat%22
 ), Sever
@@ -1758,31 +1758,27 @@
 List.of(
-%22trace%22, %22stat%22
+), List.of(
 )),%0A    
@@ -1822,38 +1822,29 @@
 ), List.of(%22
-PATH_NOT_FOUND
+trace
 %22), Severity
@@ -1860,22 +1860,42 @@
 ist.of(%22
-trace%22
+PATH_NOT_FOUND%22), List.of(
 ))%0A     
@@ -3177,20 +3177,23 @@
     var 
-rule
+matcher
  = new A
@@ -3192,39 +3192,32 @@
  = new Alert
-Config.
 Matcher(
 );%0A        r
@@ -3208,43 +3208,79 @@
 her(
-);%0A        rule.excludeErrorCodes =
+List.of(%0A                matcher(List.of(), List.of(), null, List.of(),
  Lis
@@ -3312,17 +3312,17 @@
 R_TEAM%22)
-;
+)
 %0A       
@@ -3326,51 +3326,8 @@
     
-var matcher = new AlertMatcher(List.of(rule
 ));%0A
@@ -3630,24 +3630,21 @@
 String%3E 
-errorCod
+indic
 es, Seve
@@ -3671,21 +3671,56 @@
 String%3E 
-indic
+errorCodes, List%3CString%3E excludeErrorCod
 es) %7B%0A  
@@ -3815,49 +3815,8 @@
 her.
-errorCodes = errorCodes;%0A        matcher.
 seve
@@ -3863,16 +3863,112 @@
  = indic
+es;%0A        matcher.errorCodes = errorCodes;%0A        matcher.excludeErrorCodes = excludeErrorCod
 es;%0A    

refactor unit test