package com.eactive.eai.rms.onl.apim.masking;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

/**
 * 메세지 본문/메신저ID 패턴 마스킹 + 색상강조 + XSS escape 검증.
 */
class MessagePatternMaskingUtilsTest {

	// --- 이메일 ---

	@Test
	@DisplayName("본문 이메일 — mask-email span + 표준 이메일 마스킹")
	void maskAndHighlight_email() {
		assertEquals("<span class=\"mask-email\">**st1**@test.com</span>",
				MessagePatternMaskingUtils.maskAndHighlight("test123@test.com"));
	}

	// --- 휴대폰(하이픈) ---

	@Test
	@DisplayName("본문 휴대폰(하이픈) — mask-phone span + 세그먼트별 뒤2자리 마스킹")
	void maskAndHighlight_phoneHyphen() {
		assertEquals("<span class=\"mask-phone\">010-12**-56**</span>",
				MessagePatternMaskingUtils.maskAndHighlight("010-1234-5678"));
	}

	// --- 6자리 이상 숫자 (앞 3자리 제외 전체 마스킹) ---

	@Test
	@DisplayName("본문 6자리 숫자 — 앞 3자리 제외 전체 마스킹(mask-digits)")
	void maskAndHighlight_digits6() {
		assertEquals("<span class=\"mask-digits\">123***</span>",
				MessagePatternMaskingUtils.maskAndHighlight("123456"));
	}

	@Test
	@DisplayName("본문 하이픈 없는 휴대폰(11자리) — 6자리+ 숫자 규칙 적용")
	void maskAndHighlight_phoneNoHyphen() {
		assertEquals("<span class=\"mask-digits\">010********</span>",
				MessagePatternMaskingUtils.maskAndHighlight("01012345678"));
	}

	@Test
	@DisplayName("5자리 이하 숫자는 마스킹하지 않음")
	void maskAndHighlight_digitsUnder6() {
		assertEquals("12345", MessagePatternMaskingUtils.maskAndHighlight("12345"));
	}

	// --- 우선순위 / 혼합 ---

	@Test
	@DisplayName("하이픈 휴대폰이 숫자 규칙에 이중 적용되지 않음 (phone 우선)")
	void maskAndHighlight_priority() {
		String result = MessagePatternMaskingUtils.maskAndHighlight("010-1234-5678");
		assertTrue(result.contains("mask-phone"));
		assertFalse(result.contains("mask-digits"));
	}

	@Test
	@DisplayName("텍스트 + 이메일/휴대폰/숫자 혼합 — 각 패턴별 span 생성, 일반 텍스트는 보존")
	void maskAndHighlight_mixed() {
		String result = MessagePatternMaskingUtils.maskAndHighlight(
				"인증요청 test123@test.com 전화 010-1234-5678 코드 123456 끝");
		assertTrue(result.contains("<span class=\"mask-email\">**st1**@test.com</span>"));
		assertTrue(result.contains("<span class=\"mask-phone\">010-12**-56**</span>"));
		assertTrue(result.contains("<span class=\"mask-digits\">123***</span>"));
		assertTrue(result.contains("인증요청"));
		assertTrue(result.contains("끝"));
		// 원문 일부가 그대로 노출되지 않아야 함
		assertFalse(result.contains("test123@"));
		assertFalse(result.contains("010-1234-5678"));
		assertFalse(result.contains("123456"));
	}

	// --- XSS / HTML escape ---

	@Test
	@DisplayName("매칭 외 영역의 HTML 태그는 escape 되어 무력화")
	void maskAndHighlight_escapesHtml() {
		assertEquals("&lt;b&gt;hi&lt;/b&gt;",
				MessagePatternMaskingUtils.maskAndHighlight("<b>hi</b>"));
	}

	@Test
	@DisplayName("script 태그 escape")
	void maskAndHighlight_escapesScript() {
		String result = MessagePatternMaskingUtils.maskAndHighlight("<script>alert(1)</script>");
		assertFalse(result.contains("<script>"));
		assertTrue(result.contains("&lt;script&gt;"));
	}

	@Test
	@DisplayName("앰퍼샌드 escape")
	void maskAndHighlight_escapesAmp() {
		assertEquals("a&amp;b", MessagePatternMaskingUtils.maskAndHighlight("a&b"));
	}

	// --- null / empty ---

	@Test
	@DisplayName("null·빈문자 본문은 빈문자 반환")
	void maskAndHighlight_nullEmpty() {
		assertEquals("", MessagePatternMaskingUtils.maskAndHighlight(null));
		assertEquals("", MessagePatternMaskingUtils.maskAndHighlight(""));
	}

	// --- 메신저 ID ---

	@Test
	@DisplayName("메신저ID — 뒤 2자리 마스킹")
	void maskMessengerId_normal() {
		assertEquals("kakao_ab**", MessagePatternMaskingUtils.maskMessengerId("kakao_abcd"));
	}

	@Test
	@DisplayName("메신저ID — 2자 이하 전체 마스킹")
	void maskMessengerId_short() {
		assertEquals("**", MessagePatternMaskingUtils.maskMessengerId("ab"));
		assertEquals("*", MessagePatternMaskingUtils.maskMessengerId("a"));
	}

	@Test
	@DisplayName("메신저ID — null·빈문자 방어")
	void maskMessengerId_nullEmpty() {
		assertNull(MessagePatternMaskingUtils.maskMessengerId(null));
		assertEquals("", MessagePatternMaskingUtils.maskMessengerId(""));
	}
}
