package com.nisemoe.nise.config

import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.core.Authentication
import org.springframework.security.web.SecurityFilterChain
import org.springframework.security.web.authentication.AuthenticationSuccessHandler
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler
import org.springframework.session.web.http.CookieSerializer
import org.springframework.session.web.http.DefaultCookieSerializer
import org.springframework.stereotype.Component
import org.springframework.web.cors.CorsUtils
import org.springframework.web.filter.CorsFilter
import java.util.concurrent.TimeUnit


@Configuration
@EnableWebSecurity
class SecurityConfig {

    @Value("\${COOKIE_DOMAIN_PATTERN:^.+?\\.nise\\.moe\$}")
    private lateinit var domainNamePattern: String

    @Value("\${COOKIE_SECURE:false}")
    private var cookieSecure: Boolean = false

    @Bean
    fun cookieSerializer(): CookieSerializer? {
        val serializer = DefaultCookieSerializer()
        serializer.setCookieName("SESSION")
        serializer.setCookiePath("/")
        serializer.setDomainNamePattern(domainNamePattern)
        serializer.setCookieMaxAge(TimeUnit.DAYS.toSeconds(30).toInt())
        serializer.setUseHttpOnlyCookie(cookieSecure)
        serializer.setUseSecureCookie(cookieSecure)

        return serializer
    }

    @Component
    class CustomAuthenticationSuccessHandler : AuthenticationSuccessHandler {

        override fun onAuthenticationSuccess(request: HttpServletRequest?, response: HttpServletResponse?, authentication: Authentication?) {
            response?.sendRedirect(System.getenv("ORIGIN"))
        }

    }

    @Component
    class CustomLogoutSuccessHandler : LogoutSuccessHandler {

        override fun onLogoutSuccess(request: HttpServletRequest?, response: HttpServletResponse?, authentication: Authentication?) {
            response?.sendRedirect(System.getenv("ORIGIN"))
        }

    }

    @Bean
    fun customCorsFilter(): CustomCorsFilter {
        return CustomCorsFilter()
    }

    @Bean
    fun filterChain(http: HttpSecurity): SecurityFilterChain? {
        http
            .csrf { csrf -> csrf.disable() }
            .addFilterBefore(customCorsFilter(), CorsFilter::class.java)
            .authorizeHttpRequests { auth ->
                auth
                    .requestMatchers("/user-queue").authenticated()
                    .anyRequest().permitAll()
            }
            .oauth2Login { oauthLogin ->
                oauthLogin.successHandler(CustomAuthenticationSuccessHandler())
            }
            .logout { logout ->
                logout.logoutSuccessHandler(CustomLogoutSuccessHandler())
            }
        return http.build()
    }

}
