package com.cloudhandson.vpdbackoffice.web;

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

import com.cloudhandson.vpdbackoffice.domain.masking.ColumnMaskingRule;
import com.cloudhandson.vpdbackoffice.domain.masking.MaskingRule;
import com.cloudhandson.vpdbackoffice.domain.masking.MaskingPolicyStatus;
import com.cloudhandson.vpdbackoffice.domain.masking.MaskingTemplate;
import com.cloudhandson.vpdbackoffice.domain.masking.UserMaskingRule;
import com.cloudhandson.vpdbackoffice.domain.protectedobject.ProtectedColumn;
import com.cloudhandson.vpdbackoffice.domain.protectedobject.ProtectedObject;
import com.cloudhandson.vpdbackoffice.domain.user.AppUser;
import java.nio.file.Path;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring6.SpringTemplateEngine;
import org.thymeleaf.templateresolver.FileTemplateResolver;

class MaskingRuleTemplateRenderTest {

  @Test
  void rendersRuleRegistrationAndUserExceptionPages() {
    var resolver = new FileTemplateResolver();
    resolver.setPrefix(Path.of("src/main/resources/templates").toAbsolutePath() + "/");
    resolver.setSuffix(".html");
    resolver.setTemplateMode("HTML");
    resolver.setCacheable(false);
    var engine = new SpringTemplateEngine();
    engine.setTemplateResolver(resolver);

    var object = new ProtectedObject(7L, "SGMP_POC", "CZN_COMN_USER_MST", "sgmp-poc/czn-users", "Y");
    var transactionObject = new ProtectedObject(8L, "SGMP_POC", "COMN_SALES_TXN", "sgmp-poc/sales", "Y");
    var column = new ProtectedColumn(11L, 7L, "GUID", "Y", null, "RESTRICTED", "NULLIFY");
    var rule = new MaskingRule(1L, "GAME_GUID_MASK", "게임 사용자 식별자 기본 마스킹", "TEXT_PARTIAL", "테스트", "Y");
    var columnRule = new ColumnMaskingRule(11L, 7L, "SGMP_POC", "CZN_COMN_USER_MST", "GUID",
        1L, "GAME_GUID_MASK", "게임 사용자 식별자 기본 마스킹", "TEXT_PARTIAL", "Y");
    var context = new Context(Locale.KOREAN);
    context.setVariable("_csrf", new CsrfFixture("_csrf", "test-token"));
    context.setVariable("templates", List.of(MaskingTemplate.values()));
    context.setVariable("rules", List.of(rule));
    context.setVariable("columnRules", List.of(columnRule));
    var status = new MaskingPolicyStatus(
        "SGMP_POC", "CZN_COMN_USER_MST", "SG_CZN_USER_REDACT", "YES", 1, 1, 0, 0
    );
    context.setVariable("policyStatuses", List.of(status));
    context.setVariable("policyStatusByObjectName", Map.of("CZN_COMN_USER_MST", status));
    context.setVariable("objects", List.of(object, transactionObject));
    context.setVariable("maskingTargetObjects", List.of(object, transactionObject));
    context.setVariable("sensitiveColumnsByObject", Map.of(7L, List.of(column), 8L, List.of()));
    context.setVariable("availableMaskingColumnsByObject", Map.of(7L, List.of("GUID"), 8L, List.of("GUID")));

    String rulesPage = engine.process("masking-rules", context);

    assertThat(rulesPage)
        .contains("사전 정의 마스킹 방식")
        .contains("민감 컬럼에 기본 규칙 연결")
        .contains("DBMS_REDACT.REGEXP")
        .contains("컬럼 원문 표시 허용 사용자")
        .contains("현재 DB 정책 동기화")
        .contains("자동 동기화")
        .contains("DB Redaction 컬럼")
        .contains("레거시 VPD 컬럼 제어")
        .contains("마스킹 대상 컬럼 추가")
        .contains("SGMP_POC.COMN_SALES_TXN.GUID")
        .contains("SG_CZN_USER_REDACT")
        .contains("적용됨");

    context.setVariable("users", List.of(new AppUser(2L, "sg-teamlead", "SG-001", "DATA_AI", "N", "Y")));
    context.setVariable("userRules", List.of(new UserMaskingRule(2L, "sg-teamlead", 11L,
        "SGMP_POC", "CZN_COMN_USER_MST", "GUID", "게임 사용자 식별자 기본 마스킹", "TEXT_PARTIAL", "UNMASK", "Y")));
    String userPage = engine.process("user-masking-rules", context);

    assertThat(userPage)
        .contains("컬럼 원문 표시 허용 사용자 추가")
        .contains("원문 표시 허용")
        .contains("행 접근 여부는 변경하지 않습니다")
        .contains("선택한 컬럼의 실제 적용 결과")
        .contains("data-masking-exception-preview")
        .contains("MR_11");
  }

  private record CsrfFixture(String parameterName, String token) {
  }
}
