package egovframework.filter;

import org.springframework.stereotype.Component;

import java.util.regex.Pattern;

/**
 * XSS(Cross-Site Scripting) 방지를 위한 유틸리티 클래스
 */
@Component
public class XssUtil {

    /**
     * HTML 태그를 이스케이프 처리하여 XSS 공격 방지
     * @param value 원본 문자열
     * @return 이스케이프 처리된 문자열
     */
    public String escape(String value) {
        if (value == null) {
            return null;
        }
        
        return value.replaceAll("&", "&amp;")
                   .replaceAll("<", "&lt;")
                   .replaceAll(">", "&gt;")
                   .replaceAll("\"", "&quot;")
                   .replaceAll("'", "&#x27;")
                   .replaceAll("/", "&#x2F;")
                   .replaceAll("\\(", "&#40;")
                   .replaceAll("\\)", "&#41;");
    }
    
    /**
     * 이스케이프 처리된 문자열을 원래 형태로 복원
     * @param value 이스케이프 처리된 문자열
     * @return 원본 문자열
     */
    public String unescape(String value) {
        if (value == null) {
            return null;
        }
        
        return value.replaceAll("&amp;", "&")
                   .replaceAll("&lt;", "<")
                   .replaceAll("&gt;", ">")
                   .replaceAll("&quot;", "\"")
                   .replaceAll("&#x27;", "'")
                   .replaceAll("&#x2F;", "/")
                   .replaceAll("&#40;", "(")
                   .replaceAll("&#41;", ")");
    }
    
    /**
     * HTML 에디터에서 사용하는 태그만 허용하고 나머지는 이스케이프 처리
     * @param value 원본 HTML 문자열
     * @return 안전한 HTML 문자열
     */
    public String cleanHtml(String value) {
        if (value == null) {
            return null;
        }
        
        // 허용할 HTML 태그 패턴
        String allowedTags = "<p>|<br>|<b>|<i>|<strong>|<em>|<u>|<ul>|<ol>|<li>|<h1>|<h2>|<h3>|<h4>|<h5>|<h6>|<table>|<tr>|<td>|<th>|<tbody>|<thead>|<img>|<a>|<div>|<span>";
        
        // 스크립트 태그 및 이벤트 핸들러 패턴
        String scriptPattern = "<script[^>]*>.*?</script>";
        String eventPattern = " on\\w+=\".*?\"";
        String stylePattern = " style=\".*?\"";
        String inlineFramePattern = "<iframe[^>]*>.*?</iframe>";
        String embedPattern = "<embed[^>]*>.*?</embed>";
        String objectPattern = "<object[^>]*>.*?</object>";
        
        // 스크립트 및 이벤트 핸들러 제거
        value = Pattern.compile(scriptPattern, Pattern.DOTALL | Pattern.CASE_INSENSITIVE).matcher(value).replaceAll("");
        value = Pattern.compile(eventPattern, Pattern.CASE_INSENSITIVE).matcher(value).replaceAll("");
        value = Pattern.compile(inlineFramePattern, Pattern.DOTALL | Pattern.CASE_INSENSITIVE).matcher(value).replaceAll("");
        value = Pattern.compile(embedPattern, Pattern.DOTALL | Pattern.CASE_INSENSITIVE).matcher(value).replaceAll("");
        value = Pattern.compile(objectPattern, Pattern.DOTALL | Pattern.CASE_INSENSITIVE).matcher(value).replaceAll("");
        
        // style 속성은 제한적으로 허용 (위험한 표현식 제거)
        value = Pattern.compile("expression\\s*\\(.*?\\)", Pattern.DOTALL | Pattern.CASE_INSENSITIVE).matcher(value).replaceAll("");
        value = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE).matcher(value).replaceAll("");
        value = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE).matcher(value).replaceAll("");
        
        // href 속성에서 javascript: 제거
        value = Pattern.compile("href\\s*=\\s*['\"]\\s*javascript:.*?['\"]", Pattern.CASE_INSENSITIVE).matcher(value).replaceAll("href=\"#\"");
        
        return value;
    }
    
    /**
     * 파일명에서 XSS 공격 가능성이 있는 문자 제거
     * @param filename 원본 파일명
     * @return 안전한 파일명
     */
    public String sanitizeFilename(String filename) {
        if (filename == null) {
            return null;
        }
        
        // 파일명에서 위험한 문자 제거
        return filename.replaceAll("[\\\\/:*?\"<>|]", "_");
    }
}