package com.pandoli365.bibimbap.security;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;

import java.security.SecureRandom;
import java.util.Base64;
import java.util.Map;

public final class CsrfTokens {

    public static final String SESSION_ATTRIBUTE = "csrfToken";
    public static final String HEADER_NAME = "X-CSRF-Token";
    private static final int TOKEN_BYTES = 32;
    private static final SecureRandom SECURE_RANDOM = new SecureRandom();

    private CsrfTokens() {
    }

    public static String getOrCreate(HttpSession session) {
        if (session == null) {
            return "";
        }
        Object existing = session.getAttribute(SESSION_ATTRIBUTE);
        if (existing instanceof String token && !token.isBlank()) {
            return token;
        }
        byte[] bytes = new byte[TOKEN_BYTES];
        SECURE_RANDOM.nextBytes(bytes);
        String token = Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
        session.setAttribute(SESSION_ATTRIBUTE, token);
        return token;
    }

    public static boolean isValid(HttpServletRequest request) {
        HttpSession session = request == null ? null : request.getSession(false);
        if (session == null) {
            return false;
        }
        Object expected = session.getAttribute(SESSION_ATTRIBUTE);
        if (!(expected instanceof String expectedToken) || expectedToken.isBlank()) {
            return false;
        }
        String provided = request.getHeader(HEADER_NAME);
        if (provided == null || provided.isBlank()) {
            provided = request.getParameter("_csrf");
        }
        return expectedToken.equals(provided);
    }

    public static Map<String, Object> errorBody() {
        return Map.of(
                "status", 403,
                "message", "요청 보안 토큰이 유효하지 않습니다."
        );
    }
}
