package hr.com.port.ips.eracun.helper;

import java.util.*;


// Sanitizer za HTTP headere prije logiranja.
// - Maskira tipične osjetljive headere (Authorization, X-API-Key, Cookie, …)
// - Vraća nove, “safe” mape (original ne dira)
// - Java 8 kompatibilno

public final class HttpLogSanitizer {
	
	// PRIMJERI KORIŠTENJA
	// Jednostavna mapa
	//Map<String,String> safe = HttpLogSanitizer.maskHeaders(headers);
	//logger.debug("HTTP headers (safe): " + safe);

	// Dodatni osjetljivi nazivi (npr. “CompanyId”)
	//java.util.Set<String> extra = new java.util.HashSet<>(java.util.Arrays.asList("companyid"));
	//Map<String,String> safe2 = HttpLogSanitizer.maskHeaders(headers, extra);

	// OkHttp
	//okhttp3.Headers okhttpHeaders = request.headers();
	//logger.debug("HTTP headers (safe): " + HttpLogSanitizer.maskHeaders(okhttpHeaders));

    private HttpLogSanitizer() {}

    private static final String MASK = "***";

    // Tipični osjetljivi headeri (case-insensitive)
    private static final Set<String> DEFAULT_SENSITIVE = new HashSet<>(Arrays.asList(
            "authorization",
            "proxy-authorization",
            "x-api-key", "api-key", "apikey",
            "x-auth-token", "auth", "token",
            "cookie", "set-cookie",
            "x-csrf-token", "x-xsrf-token",
            "session", "sessionid", "jsessionid"
    ));

    // Jednostavni slučaj: Map<String,String> → zamaskirana kopija.
    public static Map<String, String> maskHeaders(Map<String, String> headers) {
        return maskHeaders(headers, Collections.<String>emptySet());
    }

    // Map<String,String> uz dodatne osjetljive ključeve (lowercased). 
    public static Map<String, String> maskHeaders(Map<String, String> headers, Set<String> extraSensitiveNames) {
        if (headers == null) return Collections.emptyMap();
        Map<String, String> safe = new LinkedHashMap<>();
        for (Map.Entry<String, String> e : headers.entrySet()) {
            String name = e.getKey();
            String value = e.getValue();
            safe.put(name, isSensitive(name, extraSensitiveNames) ? MASK : value);
        }
        return safe;
    }

    // Multi-value varijanta: Map<String,List<String>> → zamaskirana kopija.
    public static Map<String, List<String>> maskHeadersMulti(Map<String, List<String>> headers) {
        return maskHeadersMulti(headers, Collections.<String>emptySet());
    }

    // Multi-value varijanta uz dodatne osjetljive ključeve.
    public static Map<String, List<String>> maskHeadersMulti(Map<String, List<String>> headers, Set<String> extraSensitiveNames) {
        if (headers == null) return Collections.emptyMap();
        Map<String, List<String>> safe = new LinkedHashMap<>();
        for (Map.Entry<String, List<String>> e : headers.entrySet()) {
            String name = e.getKey();
            List<String> vals = e.getValue();
            if (isSensitive(name, extraSensitiveNames)) {
                safe.put(name, Collections.singletonList(MASK));
            } else {
                safe.put(name, vals == null ? null : new ArrayList<>(vals));
            }
        }
        return safe;
    }

    // Brza provjera naziva headera (case-insensitive).
    public static boolean isSensitiveHeaderName(String headerName) {
        return isSensitive(headerName, Collections.<String>emptySet());
    }

    // --- (opcionalno) OkHttp overload ako koristiš OkHttp u klijentu ---
    public static Map<String, String> maskHeaders(okhttp3.Headers headers) {
        if (headers == null) return Collections.emptyMap();
        Map<String, String> safe = new LinkedHashMap<>();
        for (String name : headers.names()) {
            String value = headers.get(name);
            safe.put(name, isSensitive(name, Collections.<String>emptySet()) ? MASK : value);
        }
        return safe;
    }

    // --- internal ---

    private static boolean isSensitive(String key, Set<String> extra) {
        if (key == null) return false;
        String k = key.toLowerCase(Locale.ROOT).trim();
        if (DEFAULT_SENSITIVE.contains(k)) return true;
        if (extra != null && extra.contains(k)) return true;

        // Heuristike: pokrij i varijacije
        return k.endsWith("authorization") || k.contains("token") || k.contains("secret");
    }
}