package com.bsmlab.dfx.agent.config;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.stereotype.Component;

import java.nio.file.Paths;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
@RequiredArgsConstructor
public class BeanInitializer implements SmartInitializingSingleton {
    private final AgentConfigReader agentConfigReader;

    @Override
    public void afterSingletonsInstantiated() {
        this.configureLogback();
        log.info("✅ logger 설정 완료");
    }

    private void configureLogback() {
        AgentConfigDto agentConfigDto = this.agentConfigReader.getAgentConfigDto();
        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
        RollingFileAppender<ILoggingEvent> appender = new RollingFileAppender<>();
        appender.setContext(loggerContext);
        appender.setName(agentConfigDto.getLogging().getLogName());
        String logFilePath = Paths.get(agentConfigDto.getLogging().getLogDirectory(), agentConfigDto.getLogging().getLogFileName()).toString();
        appender.setFile(logFilePath);
        TimeBasedRollingPolicy<ILoggingEvent> rollingPolicy = new TimeBasedRollingPolicy<>();
        rollingPolicy.setContext(loggerContext);
        rollingPolicy.setParent(appender);
        rollingPolicy.setFileNamePattern(logFilePath + ".%d{yyyy-MM-dd}.gz");
        rollingPolicy.setMaxHistory(agentConfigDto.getLogging().getMaxHistory());
        rollingPolicy.setCleanHistoryOnStart(true);
        rollingPolicy.start();
        PatternLayoutEncoder encoder = new PatternLayoutEncoder();
        encoder.setContext(loggerContext);
        encoder.setPattern(agentConfigDto.getLogging().getLogPattern());
        encoder.start();
        appender.setEncoder(encoder);
        appender.setRollingPolicy(rollingPolicy);
        appender.start();
        Logger rootLogger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
        Level logLevel = Level.toLevel(agentConfigDto.getLogging().getRootLogLevel());
        rootLogger.setLevel(logLevel);
        rootLogger.detachAndStopAllAppenders();
        rootLogger.addAppender(appender);
        List<Map<String, String>> packagesListMap = agentConfigDto.getLogging().getPackages();
        if(packagesListMap != null) {
            for(Map<String, String> packagesMap : packagesListMap) {
                for(String packageName : packagesMap.keySet()) {
                    Level packageLogLevel = Level.toLevel(packagesMap.get(packageName));
                    Logger logger = loggerContext.getLogger(packageName);
                    logger.setLevel(packageLogLevel);
                    logger.setAdditive(false); // 부모 로그 방지
                    logger.detachAndStopAllAppenders();
                    logger.addAppender(appender);
                }
            }
        }
    }
}
