package com.zioinfo.cms.integration;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * GUARDiA 연계 응답 보안 새니타이저.
 *
 * <p>보안 불변 규칙: 서버 자격증명(IP/SSH 계정/비밀번호 등)을 API 응답에 절대 노출하지 않는다.
 * ITSM/Mall/CRM/OCR/BI 연계 응답을 CMS로 반환하기 전 반드시 {@link #clean(Object)}를 호출한다.
 *
 * <p>Map/List 구조를 재귀적으로 순회하며 민감 필드를 제거한다.
 */
public final class ItsmSecuritySanitizer {

    private static final Set<String> SENSITIVE_KEYS = Set.of(
        "ip_addr", "ipaddr", "ssh_user", "sshuser", "os_pw_enc", "ospwenc",
        "password", "password_enc", "passwordenc", "ssh_key", "sshkey",
        "secret", "token", "private_key", "credential"
    );

    private ItsmSecuritySanitizer() {
    }

    /**
     * 응답 데이터에서 민감 필드를 재귀 제거한다.
     *
     * @param data Map(필터링), List(각 원소 적용), 그 외(그대로 반환)
     * @return 민감 필드가 제거된 데이터
     */
    public static Object clean(Object data) {
        if (data instanceof Map<?, ?> map) {
            Map<String, Object> cleaned = new LinkedHashMap<>();
            for (Map.Entry<?, ?> entry : map.entrySet()) {
                String key = String.valueOf(entry.getKey());
                if (isSensitive(key)) {
                    continue;
                }
                cleaned.put(key, clean(entry.getValue()));
            }
            return cleaned;
        }
        if (data instanceof List<?> list) {
            List<Object> cleaned = new ArrayList<>(list.size());
            for (Object item : list) {
                cleaned.add(clean(item));
            }
            return cleaned;
        }
        return data;
    }

    private static boolean isSensitive(String key) {
        if (key == null) {
            return false;
        }
        return SENSITIVE_KEYS.contains(key.toLowerCase());
    }
}
