package click.kamil.springstatemachineexporter.analysis.enricher.path;

import click.kamil.springstatemachineexporter.analysis.enricher.AnalysisEnricher;
import click.kamil.springstatemachineexporter.analysis.model.AnalysisResult;
import click.kamil.springstatemachineexporter.analysis.model.CallChain;
import click.kamil.springstatemachineexporter.analysis.model.TriggerPoint;
import click.kamil.springstatemachineexporter.analysis.service.CodebaseIntelligenceProvider;
import click.kamil.springstatemachineexporter.ast.common.CodebaseContext;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
public class ForwardPathEstimationEnricher implements AnalysisEnricher {

    private final boolean isEnabled;
    private final PathValueEstimator estimator;

    public ForwardPathEstimationEnricher() {
        this.isEnabled = Boolean.parseBoolean(System.getProperty("analyzer.forward-path-estimation.enabled", "false"));
        this.estimator = new SymbolicPathValueEstimator();
    }

    @Override
    public void enrich(AnalysisResult result, CodebaseContext context, CodebaseIntelligenceProvider intelligence) {
        if (!isEnabled || result.getMetadata() == null || result.getMetadata().getCallChains() == null) {
            return;
        }

        log.info("Running Symbolic Forward Path Analysis for {}", result.getName());
        
        List<CallChain> chains = result.getMetadata().getCallChains();
        List<CallChain> updatedChains = chains.stream().map(chain -> {
            if (chain.getTriggerPoint() == null || chain.getTriggerPoint().getEvent() == null) return chain;
            
            // If the event looks like a dynamic variable (no dots, not an enum format)
            if (!chain.getTriggerPoint().getEvent().contains(".")) {
                List<String> estimatedValues = estimator.estimatePossibleValues(chain, context);
                if (estimatedValues != null && !estimatedValues.isEmpty()) {
                    log.info("Symbolic Path Analysis estimated values for {} -> {}", chain.getTriggerPoint().getEvent(), estimatedValues);
                    
                    List<String> polyEvents = new ArrayList<>();
                    if (chain.getTriggerPoint().getPolymorphicEvents() != null) {
                        polyEvents.addAll(chain.getTriggerPoint().getPolymorphicEvents());
                    }
                    polyEvents.addAll(estimatedValues);
                    
                    TriggerPoint newTp = chain.getTriggerPoint().toBuilder()
                            .polymorphicEvents(polyEvents)
                            .build();
                            
                    return chain.toBuilder().triggerPoint(newTp).build();
                }
            }
            return chain;
        }).collect(Collectors.toList());
        click.kamil.springstatemachineexporter.analysis.model.CodebaseMetadata updatedMetadata = 
                click.kamil.springstatemachineexporter.analysis.model.CodebaseMetadata.builder()
                .triggers(result.getMetadata().getTriggers())
                .entryPoints(result.getMetadata().getEntryPoints())
                .callChains(updatedChains)
                .properties(result.getMetadata().getProperties())
                .build();

        result.setMetadata(updatedMetadata);
    }
}
