package com.xindazhou.framework.apilog.config;

import com.xindazhou.framework.apilog.core.filter.ApiAccessLogFilter;
import com.xindazhou.framework.apilog.core.interceptor.ApiAccessLogInterceptor;
import com.xindazhou.framework.apilog.core.service.ApiAccessLogStorageStrategy;
import com.xindazhou.framework.apilog.core.service.impl.LogOnlyStorageStrategy;
import com.xindazhou.framework.common.enums.WebFilterOrderEnum;
import com.xindazhou.framework.web.config.WebProperties;
import com.xindazhou.framework.web.config.XdzWebAutoConfiguration;
import jakarta.servlet.Filter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.io.File;

@AutoConfiguration(after = XdzWebAutoConfiguration.class)
@EnableConfigurationProperties(ApiAccessLogProperties.class)
@EnableAsync
public class XdzApiLogAutoConfiguration implements WebMvcConfigurer {

    /**
     * 创建 LogOnlyStorageStrategy Bean（log-only 模式，默认）
     */
    @Bean
    @ConditionalOnMissingBean(ApiAccessLogStorageStrategy.class)
    @ConditionalOnProperty(prefix = "xdz.access-log", name = "mode", havingValue = "log-only", matchIfMissing = true)
    public LogOnlyStorageStrategy logOnlyStorageStrategy(
            @Value("${spring.application.name}") String applicationName,
            ApiAccessLogProperties properties) {
        String logFilePath = properties.getLogFilePath();
        if (logFilePath == null || logFilePath.isEmpty()) {
            // 默认路径：${user.home}/logs/${spring.application.name}-access.log
            String userHome = System.getProperty("user.home");
            logFilePath = userHome + File.separator + "logs" + File.separator + applicationName + "-access.log";
        }
        return new LogOnlyStorageStrategy(applicationName, logFilePath);
    }

    /**
     * 创建 ApiAccessLogFilter Bean，记录 API 请求日志
     */
    @Bean
    @ConditionalOnProperty(prefix = "xdz.access-log", value = "enable", matchIfMissing = true) // 允许使用 xdz.access-log.enable=false 禁用访问日志
    @ConditionalOnBean(ApiAccessLogStorageStrategy.class)
    public FilterRegistrationBean<ApiAccessLogFilter> apiAccessLogFilter(WebProperties webProperties,
                                                                         @Value("${spring.application.name}") String applicationName,
                                                                         ApiAccessLogStorageStrategy storageStrategy) {
        ApiAccessLogFilter filter = new ApiAccessLogFilter(webProperties, applicationName, storageStrategy);
        return createFilterBean(filter, WebFilterOrderEnum.API_ACCESS_LOG_FILTER);
    }

    private static <T extends Filter> FilterRegistrationBean<T> createFilterBean(T filter, Integer order) {
        FilterRegistrationBean<T> bean = new FilterRegistrationBean<>(filter);
        bean.setOrder(order);
        return bean;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new ApiAccessLogInterceptor());
    }

}
