package com.cameleer.server.core.detail;

import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Nested tree node representing a single processor execution within a route.
 * <p>
 * The tree structure is reconstructed from individual processor records stored in PostgreSQL.
 * Each node may have children (e.g., processors inside a split or try-catch block).
 */
public final class ProcessorNode {

    private final String processorId;
    private final String processorType;
    private final String status;
    private final Instant startTime;
    private final Instant endTime;
    private final long durationMs;
    private final String errorMessage;
    private final String errorStackTrace;
    private final Map<String, String> attributes;
    private final Integer iteration;
    private final Integer iterationSize;
    private final Integer loopIndex;
    private final Integer loopSize;
    private final Integer splitIndex;
    private final Integer splitSize;
    private final Integer multicastIndex;
    private final String resolvedEndpointUri;
    private final String errorType;
    private final String errorCategory;
    private final String rootCauseType;
    private final String rootCauseMessage;
    private final String errorHandlerType;
    private final String circuitBreakerState;
    private final Boolean fallbackTriggered;
    private final Boolean filterMatched;
    private final Boolean duplicateMessage;
    private final boolean hasTraceData;
    private final List<ProcessorNode> children;

    public ProcessorNode(String processorId, String processorType, String status,
                         Instant startTime, Instant endTime, long durationMs,
                         String errorMessage, String errorStackTrace,
                         Map<String, String> attributes,
                         Integer iteration, Integer iterationSize,
                         Integer loopIndex, Integer loopSize,
                         Integer splitIndex, Integer splitSize,
                         Integer multicastIndex,
                         String resolvedEndpointUri,
                         String errorType, String errorCategory,
                         String rootCauseType, String rootCauseMessage,
                         String errorHandlerType, String circuitBreakerState,
                         Boolean fallbackTriggered,
                         Boolean filterMatched, Boolean duplicateMessage,
                         boolean hasTraceData) {
        this.processorId = processorId;
        this.processorType = processorType;
        this.status = status;
        this.startTime = startTime;
        this.endTime = endTime;
        this.durationMs = durationMs;
        this.errorMessage = errorMessage;
        this.errorStackTrace = errorStackTrace;
        this.attributes = attributes;
        this.iteration = iteration;
        this.iterationSize = iterationSize;
        this.loopIndex = loopIndex;
        this.loopSize = loopSize;
        this.splitIndex = splitIndex;
        this.splitSize = splitSize;
        this.multicastIndex = multicastIndex;
        this.resolvedEndpointUri = resolvedEndpointUri;
        this.errorType = errorType;
        this.errorCategory = errorCategory;
        this.rootCauseType = rootCauseType;
        this.rootCauseMessage = rootCauseMessage;
        this.errorHandlerType = errorHandlerType;
        this.circuitBreakerState = circuitBreakerState;
        this.fallbackTriggered = fallbackTriggered;
        this.filterMatched = filterMatched;
        this.duplicateMessage = duplicateMessage;
        this.hasTraceData = hasTraceData;
        this.children = new ArrayList<>();
    }

    public void addChild(ProcessorNode child) {
        children.add(child);
    }

    public String getProcessorId() { return processorId; }
    public String getProcessorType() { return processorType; }
    public String getStatus() { return status; }
    public Instant getStartTime() { return startTime; }
    public Instant getEndTime() { return endTime; }
    public long getDurationMs() { return durationMs; }
    public String getErrorMessage() { return errorMessage; }
    public String getErrorStackTrace() { return errorStackTrace; }
    public Map<String, String> getAttributes() { return attributes; }
    public Integer getIteration() { return iteration; }
    public Integer getIterationSize() { return iterationSize; }
    public Integer getLoopIndex() { return loopIndex; }
    public Integer getLoopSize() { return loopSize; }
    public Integer getSplitIndex() { return splitIndex; }
    public Integer getSplitSize() { return splitSize; }
    public Integer getMulticastIndex() { return multicastIndex; }
    public String getResolvedEndpointUri() { return resolvedEndpointUri; }
    public String getErrorType() { return errorType; }
    public String getErrorCategory() { return errorCategory; }
    public String getRootCauseType() { return rootCauseType; }
    public String getRootCauseMessage() { return rootCauseMessage; }
    public String getErrorHandlerType() { return errorHandlerType; }
    public String getCircuitBreakerState() { return circuitBreakerState; }
    public Boolean getFallbackTriggered() { return fallbackTriggered; }
    public Boolean getFilterMatched() { return filterMatched; }
    public Boolean getDuplicateMessage() { return duplicateMessage; }
    public boolean isHasTraceData() { return hasTraceData; }
    public List<ProcessorNode> getChildren() { return List.copyOf(children); }
}
