"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.scanDroidNativeUsageEntries = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const droid_dashboard_service_1 = require("../services/droid-dashboard-service");
const ui_1 = require("../../utils/ui");
const sqlite_cli_1 = require("./sqlite-cli");
const DROID_COST_BATCH_SIZE = 1000;
function isObject(value) {
    return typeof value === 'object' && value !== null;
}
function asString(value) {
    return typeof value === 'string' && value.trim().length > 0 ? value.trim() : null;
}
function asNumber(value) {
    const numeric = typeof value === 'number' ? value : Number(value);
    return Number.isFinite(numeric) && numeric >= 0 ? numeric : null;
}
function isCcsManagedSelector(selector) {
    return selector.startsWith('custom:CCS-') || selector.startsWith('custom:ccs-');
}
function buildSelectorAlias(displayName, index) {
    return `${displayName.trim().replace(/\s+/g, '-')}-${index}`;
}
function normalizeCustomModels(settings) {
    const raw = settings.customModels ?? settings.custom_models;
    if (Array.isArray(raw)) {
        return raw.filter((entry) => isObject(entry));
    }
    if (isObject(raw)) {
        return Object.values(raw).filter((entry) => isObject(entry));
    }
    return [];
}
function buildCustomModelMap(settingsPath) {
    const selectors = new Map();
    if (!fs.existsSync(settingsPath))
        return selectors;
    try {
        const parsed = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
        if (!isObject(parsed))
            return selectors;
        for (const [index, entry] of normalizeCustomModels(parsed).entries()) {
            const displayName = asString(entry.displayName ?? entry.model_display_name);
            const model = asString(entry.model);
            if (!displayName || !model)
                continue;
            selectors.set(`custom:${buildSelectorAlias(displayName, index)}`, model);
        }
    }
    catch {
        return selectors;
    }
    return selectors;
}
function collectSessionFiles(dir, suffix, results = []) {
    if (!fs.existsSync(dir))
        return results;
    for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
        const entryPath = path.join(dir, entry.name);
        if (entry.isDirectory()) {
            collectSessionFiles(entryPath, suffix, results);
            continue;
        }
        if (entry.isFile() && entry.name.endsWith(suffix)) {
            results.push(entryPath);
        }
    }
    return results;
}
function readSessionStartMetadata(filePath) {
    try {
        const firstLine = fs.readFileSync(filePath, 'utf8').split('\n')[0];
        const parsed = JSON.parse(firstLine);
        if (parsed?.type !== 'session_start')
            return null;
        return {
            projectPath: asString(parsed.cwd) ?? '/',
            version: typeof parsed.version === 'number'
                ? String(parsed.version)
                : (asString(parsed.version) ?? undefined),
        };
    }
    catch {
        return null;
    }
}
function loadSessionMetadata(factoryDir) {
    const metadata = new Map();
    const selectorMap = buildCustomModelMap(path.join(factoryDir, 'settings.json'));
    const sessionsDir = path.join(factoryDir, 'sessions');
    for (const settingsPath of collectSessionFiles(sessionsDir, '.settings.json')) {
        const sessionId = path.basename(settingsPath, '.settings.json');
        const jsonlPath = settingsPath.replace(/\.settings\.json$/, '.jsonl');
        const start = readSessionStartMetadata(jsonlPath);
        if (!start)
            continue;
        try {
            const parsed = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
            const rawSelector = asString(parsed?.model) ?? 'unknown-droid-model';
            metadata.set(sessionId, {
                model: selectorMap.get(rawSelector) ?? rawSelector,
                projectPath: start.projectPath,
                rawSelector,
                version: start.version,
            });
        }
        catch {
            continue;
        }
    }
    return metadata;
}
async function scanDroidNativeUsageEntries(options = {}) {
    const query = options.querySqliteJson ?? sqlite_cli_1.querySqliteJson;
    const { settingsPath } = (0, droid_dashboard_service_1.resolveDroidConfigPaths)({
        env: options.env,
        homeDir: options.homeDir,
    });
    const factoryDir = path.dirname(settingsPath);
    const costsDbPath = path.join(factoryDir, 'costs.db');
    if (!fs.existsSync(costsDbPath))
        return [];
    const rows = [];
    let offset = 0;
    while (true) {
        const batch = await query(costsDbPath, `SELECT session_id, timestamp, input_tokens, output_tokens FROM costs ` +
            `ORDER BY timestamp ASC LIMIT ${DROID_COST_BATCH_SIZE} OFFSET ${offset};`);
        if (!batch.length)
            break;
        rows.push(...batch);
        if (batch.length < DROID_COST_BATCH_SIZE)
            break;
        offset += batch.length;
    }
    if (!rows.length)
        return [];
    const metadata = loadSessionMetadata(factoryDir);
    const entries = [];
    let skippedRowsWithoutMetadata = 0;
    for (const row of rows) {
        if (!isObject(row))
            continue;
        const sessionId = asString(row.session_id);
        const timestamp = asString(row.timestamp);
        const inputTokens = asNumber(row.input_tokens);
        const outputTokens = asNumber(row.output_tokens);
        if (!sessionId || !timestamp || inputTokens === null || outputTokens === null)
            continue;
        const session = metadata.get(sessionId);
        if (!session) {
            skippedRowsWithoutMetadata++;
            continue;
        }
        if (!options.includeCcsManagedSessions && isCcsManagedSelector(session.rawSelector)) {
            continue;
        }
        entries.push({
            inputTokens,
            outputTokens,
            cacheCreationTokens: 0,
            cacheReadTokens: 0,
            model: session.model,
            sessionId,
            timestamp,
            projectPath: session.projectPath,
            version: session.version,
            target: 'droid',
        });
    }
    if (skippedRowsWithoutMetadata > 0) {
        console.log((0, ui_1.warn)(`Skipped ${skippedRowsWithoutMetadata} Droid native cost row(s) without local session metadata`));
    }
    return entries;
}
exports.scanDroidNativeUsageEntries = scanDroidNativeUsageEntries;
//# sourceMappingURL=droid-native-usage-collector.js.map