package egovframework.config;

import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.ErrorPageRegistrar;
import org.springframework.boot.web.server.ErrorPageRegistry;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;

/**
 * 에러 페이지 설정을 위한 설정 클래스
 * 404, 500 등의 HTTP 에러 코드에 대한 커스텀 에러 페이지를 매핑합니다.
 */
@Configuration
public class EgovErrorConfig {

    /**
     * ErrorPageRegistrar 빈을 생성하여 에러 페이지를 등록합니다.
     * 
     * @return ErrorPageRegistrar 구현체
     */
    @Bean
    public ErrorPageRegistrar errorPageRegistrar() {
        return new ErrorPageRegistrar() {
            @Override
            public void registerErrorPages(ErrorPageRegistry registry) {
                // 404 에러 페이지 설정
                ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/error/404");

                // 403 에러 페이지 설정 (권한 없음)
                ErrorPage error403Page = new ErrorPage(HttpStatus.FORBIDDEN, "/error/404");

                // AccessDeniedException 예외 처리를 위한 에러 페이지 설정
                ErrorPage accessDeniedPage = new ErrorPage(egovframework.exception.AccessDeniedException.class, "/error/404");

                // 클라이언트 에러(4xx) 페이지 설정
                // 400 에러 페이지 설정 (잘못된 요청)
                ErrorPage error400Page = new ErrorPage(HttpStatus.BAD_REQUEST, "/error/404");
                
                // 401 에러 페이지 설정 (인증 실패)
                ErrorPage error401Page = new ErrorPage(HttpStatus.UNAUTHORIZED, "/error/404");
                
                // 405 에러 페이지 설정 (허용되지 않는 메소드)
                ErrorPage error405Page = new ErrorPage(HttpStatus.METHOD_NOT_ALLOWED, "/error/404");
                
                // 406 에러 페이지 설정 (허용되지 않는 형식)
                ErrorPage error406Page = new ErrorPage(HttpStatus.NOT_ACCEPTABLE, "/error/404");
                
                // 408 에러 페이지 설정 (요청 시간 초과)
                ErrorPage error408Page = new ErrorPage(HttpStatus.REQUEST_TIMEOUT, "/error/404");
                
                // 409 에러 페이지 설정 (충돌)
                ErrorPage error409Page = new ErrorPage(HttpStatus.CONFLICT, "/error/404");
                
                // 410 에러 페이지 설정 (리소스 사라짐)
                ErrorPage error410Page = new ErrorPage(HttpStatus.GONE, "/error/404");
                
                // 413 에러 페이지 설정 (요청 엔티티가 너무 큼)
                ErrorPage error413Page = new ErrorPage(HttpStatus.PAYLOAD_TOO_LARGE, "/error/404");
                
                // 414 에러 페이지 설정 (URI가 너무 김)
                ErrorPage error414Page = new ErrorPage(HttpStatus.URI_TOO_LONG, "/error/404");
                
                // 415 에러 페이지 설정 (지원되지 않는 미디어 타입)
                ErrorPage error415Page = new ErrorPage(HttpStatus.UNSUPPORTED_MEDIA_TYPE, "/error/404");
                
                // 429 에러 페이지 설정 (너무 많은 요청)
                ErrorPage error429Page = new ErrorPage(HttpStatus.TOO_MANY_REQUESTS, "/error/404");

                // 500 에러 페이지 설정
                ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500");

                // 기타 서버 에러 페이지 설정
                ErrorPage error501Page = new ErrorPage(HttpStatus.NOT_IMPLEMENTED, "/error/500");
                ErrorPage error502Page = new ErrorPage(HttpStatus.BAD_GATEWAY, "/error/500");
                ErrorPage error503Page = new ErrorPage(HttpStatus.SERVICE_UNAVAILABLE, "/error/500");
                ErrorPage error504Page = new ErrorPage(HttpStatus.GATEWAY_TIMEOUT, "/error/500");
                ErrorPage error505Page = new ErrorPage(HttpStatus.HTTP_VERSION_NOT_SUPPORTED, "/error/500");

                // 예외 처리를 위한 에러 페이지 설정
                ErrorPage runtimeExceptionPage = new ErrorPage(RuntimeException.class, "/error/500");
                
                // 추가 예외 처리를 위한 에러 페이지 설정
                ErrorPage illegalArgumentExceptionPage = new ErrorPage(IllegalArgumentException.class, "/error/500");
                ErrorPage nullPointerExceptionPage = new ErrorPage(NullPointerException.class, "/error/500");
                ErrorPage illegalStateExceptionPage = new ErrorPage(IllegalStateException.class, "/error/500");
                ErrorPage ioExceptionPage = new ErrorPage(java.io.IOException.class, "/error/500");
                ErrorPage sqlExceptionPage = new ErrorPage(java.sql.SQLException.class, "/error/500");
                ErrorPage dataAccessExceptionPage = new ErrorPage(org.springframework.dao.DataAccessException.class, "/error/500");
                ErrorPage arithmeticExceptionPage = new ErrorPage(ArithmeticException.class, "/error/500");
                ErrorPage classNotFoundExceptionPage = new ErrorPage(ClassNotFoundException.class, "/error/500");
                ErrorPage noSuchMethodExceptionPage = new ErrorPage(NoSuchMethodException.class, "/error/500");
                ErrorPage indexOutOfBoundsExceptionPage = new ErrorPage(IndexOutOfBoundsException.class, "/error/500");
                ErrorPage concurrentModificationExceptionPage = new ErrorPage(java.util.ConcurrentModificationException.class, "/error/500");

                // 에러 페이지 등록
                registry.addErrorPages(
                    // 4xx 에러
                    error400Page, error401Page, error403Page, error404Page, error405Page, 
                    error406Page, error408Page, error409Page, error410Page, error413Page, 
                    error414Page, error415Page, error429Page,
                    
                    // 5xx 에러
                    error500Page, error501Page, error502Page, error503Page, error504Page, error505Page,
                    
                    // 예외 처리
                    runtimeExceptionPage, illegalArgumentExceptionPage, nullPointerExceptionPage, 
                    illegalStateExceptionPage, ioExceptionPage, sqlExceptionPage, 
                    dataAccessExceptionPage, arithmeticExceptionPage, classNotFoundExceptionPage,
                    noSuchMethodExceptionPage, indexOutOfBoundsExceptionPage, concurrentModificationExceptionPage,
                    accessDeniedPage
                );
            }
        };
    }
}
