/*
 * Copyright 2026, Jaime Terrats.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { randomBytes } from 'node:crypto';
import { writeFileSync } from 'node:fs';
import { join } from 'node:path';
import { appendJsonlFile, ensureDir, readJsonlFile } from './file-writer.js';
import { DEFAULT_RULES, redactRecord } from './pii-redactor.js';
const STATE_DIR = '.setup-agents/state';
const STATE_FILES = ['evidence.jsonl', 'decisions.jsonl', 'handoffs.jsonl', 'reviews.jsonl'];
const AUDIT_FILE = '.setup-agents/state/telemetry-audit.jsonl';
export function validateConsent(level) {
    return level !== 'none';
}
export function collectRecords(cwd) {
    const records = [];
    const stateDir = join(cwd, STATE_DIR);
    for (const file of STATE_FILES) {
        const filePath = join(stateDir, file);
        const fileRecords = readJsonlFile(filePath);
        records.push(...fileRecords);
    }
    return records;
}
function rulesForConsent(consentLevel) {
    switch (consentLevel) {
        case 'identified':
            return [];
        case 'pseudonymous':
            return DEFAULT_RULES.filter((r) => r.name === 'email' || r.name === 'ipv4');
        default:
            return [...DEFAULT_RULES];
    }
}
function serializeJsonl(records) {
    return records.map((r) => JSON.stringify(r)).join('\n') + (records.length > 0 ? '\n' : '');
}
function serializeCsv(records) {
    if (records.length === 0)
        return '';
    const allKeys = new Set();
    for (const record of records) {
        for (const key of Object.keys(record)) {
            allKeys.add(key);
        }
    }
    const columns = [...allKeys].sort();
    const escapeCsv = (val) => {
        const str = val === null || val === undefined ? '' : String(val);
        if (str.includes(',') || str.includes('"') || str.includes('\n')) {
            return `"${str.replace(/"/g, '""')}"`;
        }
        return str;
    };
    const header = columns.join(',');
    const rows = records.map((r) => columns.map((col) => escapeCsv(r[col])).join(','));
    return [header, ...rows].join('\n') + '\n';
}
export function exportTelemetry(cwd, options) {
    if (!validateConsent(options.consentLevel)) {
        throw new Error('Export blocked: consent level is "none". User has not granted telemetry consent.');
    }
    const format = options.format ?? 'jsonl';
    const dryRun = options.dryRun ?? false;
    const records = collectRecords(cwd);
    const rules = rulesForConsent(options.consentLevel);
    let totalRedactions = 0;
    const redactedRecords = [];
    for (const record of records) {
        if (rules.length === 0) {
            redactedRecords.push(record);
        }
        else {
            const { output, redactionCount } = redactRecord(record, rules);
            redactedRecords.push(output);
            totalRedactions += redactionCount;
        }
    }
    const serialized = format === 'csv' ? serializeCsv(redactedRecords) : serializeJsonl(redactedRecords);
    const outputPath = options.outputPath ?? join(cwd, `.setup-agents/exports/telemetry-export.${format}`);
    if (!dryRun) {
        ensureDir(join(outputPath, '..'));
        writeFileSync(outputPath, serialized, 'utf8');
    }
    const auditId = randomBytes(8).toString('hex');
    const auditEntry = {
        id: auditId,
        timestamp: new Date().toISOString(),
        consentLevel: options.consentLevel,
        format,
        recordCount: redactedRecords.length,
        redactedFields: totalRedactions,
        dryRun,
        ...(dryRun ? {} : { outputPath }),
    };
    if (!dryRun) {
        appendJsonlFile(join(cwd, AUDIT_FILE), auditEntry);
    }
    return {
        recordCount: redactedRecords.length,
        format,
        outputPath: dryRun ? undefined : outputPath,
        dryRun,
        redactedFields: totalRedactions,
        auditId,
    };
}
//# sourceMappingURL=telemetry-export.js.map