/**
 * Session logger — NDJSON ログ書き出し専用モジュール
 *
 * WorkflowEngine のイベントを受け取り、NDJSON セッションログへ追記する責務を担う。
 */
import { appendNdjsonLine, } from '../../../infra/fs/index.js';
import { isDebugEnabled, writePromptLog } from '../../../shared/utils/index.js';
import { sanitizeTextForStorage } from './traceReportRedaction.js';
import { buildWorkflowStepScopeKey } from './workflowStepScope.js';
import { SessionLoggerPhaseTracker } from './sessionLoggerPhaseTracker.js';
import { buildInteractiveRecords, buildPhaseCompleteRecord, buildPhaseJudgeStageRecord, buildPhaseStartRecord, buildPromptLogRecord, buildStepCompleteRecord, buildStepStartRecord, buildWorkflowAbortRecord, buildWorkflowCompleteRecord, } from './sessionLoggerRecordFactory.js';
export class SessionLogger {
    ndjsonLogPath;
    allowSensitiveData;
    phaseTracker = new SessionLoggerPhaseTracker();
    activeStepIterations = new Map();
    ndjsonRecords = [];
    promptRecords = [];
    currentIteration = 0;
    constructor(ndjsonLogPath, allowSensitiveData) {
        this.ndjsonLogPath = ndjsonLogPath;
        this.allowSensitiveData = allowSensitiveData;
    }
    writeInteractiveMetadata(meta) {
        const [startRecord, endRecord] = buildInteractiveRecords(meta, this.sanitizeText.bind(this));
        this.appendRecord(startRecord);
        this.appendRecord(endRecord);
    }
    setIteration(iteration) {
        this.currentIteration = iteration;
    }
    onPhaseStart(step, phase, phaseName, instruction, promptParts, workflowStack, phaseExecutionId, iteration) {
        if (!instruction) {
            throw new Error(`Missing phase instruction for ${step.name}:${phase}`);
        }
        const debugEnabled = isDebugEnabled();
        const resolvedPhaseExecutionId = this.phaseTracker.trackStart({
            stepName: step.name,
            phase,
            phaseExecutionId,
            iteration,
            promptParts,
            capturePrompt: debugEnabled,
        });
        const record = buildPhaseStartRecord(step, phase, phaseName, instruction, promptParts, workflowStack, resolvedPhaseExecutionId, iteration, this.sanitizeText.bind(this));
        this.appendRecord(record);
    }
    onPhaseComplete(step, phase, phaseName, content, phaseStatus, phaseError, workflowStack, phaseExecutionId, iteration) {
        if (!phaseStatus) {
            throw new Error(`Missing phase status for ${step.name}:${phase}`);
        }
        const debugEnabled = isDebugEnabled();
        const trackedPhase = this.phaseTracker.trackCompletion({
            stepName: step.name,
            phase,
            phaseExecutionId,
            iteration,
            requirePrompt: debugEnabled,
        });
        const completedAt = new Date().toISOString();
        const record = buildPhaseCompleteRecord(step, phase, phaseName, content, phaseStatus, phaseError, workflowStack, trackedPhase.phaseExecutionId, iteration, completedAt, this.sanitizeText.bind(this));
        this.appendRecord(record);
        if (debugEnabled && trackedPhase.promptParts) {
            const promptRecord = buildPromptLogRecord(step, phase, iteration ?? this.currentIteration, trackedPhase.phaseExecutionId, trackedPhase.promptParts, content, completedAt, this.sanitizeText.bind(this));
            writePromptLog(promptRecord);
            this.promptRecords.push(promptRecord);
        }
    }
    onJudgeStage(step, phase, phaseName, entry, workflowStack, phaseExecutionId, iteration) {
        const resolvedPhaseExecutionId = this.phaseTracker.resolveExistingExecutionId({
            stepName: step.name,
            phase,
            phaseExecutionId,
            iteration,
        });
        const record = buildPhaseJudgeStageRecord(step, phase, phaseName, entry, workflowStack, resolvedPhaseExecutionId, iteration, this.sanitizeText.bind(this));
        this.appendRecord(record);
    }
    onStepStart(step, iteration, instruction, workflowStack, providerInfo) {
        this.currentIteration = iteration;
        this.activeStepIterations.set(buildWorkflowStepScopeKey(step.name, workflowStack), iteration);
        const record = buildStepStartRecord(step, iteration, instruction, workflowStack, this.sanitizeText.bind(this), providerInfo);
        this.appendRecord(record);
    }
    onStepComplete(step, response, instruction, workflowStack) {
        const stepScopeKey = buildWorkflowStepScopeKey(step.name, workflowStack);
        const iteration = this.activeStepIterations.get(stepScopeKey);
        if (iteration == null) {
            throw new Error(`Missing step iteration for completion: ${step.name}`);
        }
        this.activeStepIterations.delete(stepScopeKey);
        const record = buildStepCompleteRecord(step, response, instruction, iteration, workflowStack, this.sanitizeText.bind(this));
        this.appendRecord(record);
    }
    onWorkflowComplete(state) {
        this.appendRecord(buildWorkflowCompleteRecord(state));
    }
    onWorkflowAbort(state, reason) {
        this.appendRecord(buildWorkflowAbortRecord(state, reason, this.sanitizeText.bind(this)));
    }
    getNdjsonRecords() {
        return [...this.ndjsonRecords];
    }
    getPromptRecords() {
        return [...this.promptRecords];
    }
    appendRecord(record) {
        this.ndjsonRecords.push(record);
        appendNdjsonLine(this.ndjsonLogPath, record);
    }
    sanitizeText(text) {
        return sanitizeTextForStorage(text, this.allowSensitiveData);
    }
}
//# sourceMappingURL=sessionLogger.js.map