package com.ga.api.support;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;

/**
 * 테스트용 보안 설정.
 * - JWT 필터 없이 인증 여부만 체크
 * - 미인증 요청 → 401
 * - WebMvcConfig 를 포함하지 않으므로 Jackson 기본 설정 사용
 */
@TestConfiguration
public class TestSecurityConfig {

    /**
     * JavaTimeModule 포함한 ObjectMapper. WebMvcConfig 대신 사용.
     * @WebMvcTest 에서 LocalDateTime 직렬화 실패를 방지한다.
     */
    @Bean
    @Primary
    public ObjectMapper testObjectMapper() {
        return new ObjectMapper()
                .registerModule(new JavaTimeModule())
                .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    }

    /**
     * SecurityConfig.filter() 를 오버라이드한다.
     * spring.main.allow-bean-definition-overriding=true 가 필요하다.
     */
    @Bean("filter")
    public SecurityFilterChain testFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(AbstractHttpConfigurer::disable)
            .sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .formLogin(AbstractHttpConfigurer::disable)
            .httpBasic(AbstractHttpConfigurer::disable)
            .exceptionHandling(eh -> eh
                .authenticationEntryPoint((req, res, ex) ->
                        res.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized")))
            .authorizeHttpRequests(a -> a.anyRequest().authenticated());
        return http.build();
    }
}
