"use strict";
/**
 * Remote Auth Fetcher
 * Fetches and transforms auth data from remote CLIProxyAPI.
 */
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.fetchRemoteAuthStatus = void 0;
const https = __importStar(require("https"));
const proxy_target_resolver_1 = require("../proxy/proxy-target-resolver");
const provider_capabilities_1 = require("../provider-capabilities");
/** Timeout for remote fetch requests (ms) */
const REMOTE_FETCH_TIMEOUT_MS = 5000;
async function fetchRemoteAuthResponse(url, headers, target) {
    if (target.protocol !== 'https' || !target.allowSelfSigned) {
        const controller = new AbortController();
        const timeoutId = setTimeout(() => controller.abort(), REMOTE_FETCH_TIMEOUT_MS);
        try {
            return await fetch(url, {
                signal: controller.signal,
                headers,
            });
        }
        finally {
            clearTimeout(timeoutId);
        }
    }
    return new Promise((resolve, reject) => {
        const agent = new https.Agent({ rejectUnauthorized: false });
        let settled = false;
        const settle = (callback) => {
            if (settled)
                return;
            settled = true;
            clearTimeout(timeoutId);
            callback();
        };
        const timeoutId = setTimeout(() => {
            const timeoutError = new Error('Request timeout');
            req.destroy(timeoutError);
            settle(() => reject(timeoutError));
        }, REMOTE_FETCH_TIMEOUT_MS);
        const req = https.request(url, {
            method: 'GET',
            headers,
            agent,
            timeout: REMOTE_FETCH_TIMEOUT_MS,
        }, (res) => {
            let body = '';
            res.setEncoding('utf8');
            res.on('data', (chunk) => {
                body += chunk;
            });
            res.on('end', () => {
                settle(() => resolve(new Response(body, {
                    status: res.statusCode || 500,
                    statusText: res.statusMessage ?? '',
                    headers: typeof res.headers['content-type'] === 'string'
                        ? { 'Content-Type': res.headers['content-type'] }
                        : undefined,
                })));
            });
        });
        req.on('error', (error) => {
            settle(() => reject(error));
        });
        req.on('timeout', () => {
            const timeoutError = new Error('Request timeout');
            req.destroy(timeoutError);
            settle(() => reject(timeoutError));
        });
        req.end();
    });
}
/**
 * Fetch auth status from remote CLIProxyAPI
 * @throws Error if remote is unreachable or returns error
 */
async function fetchRemoteAuthStatus(target) {
    const proxyTarget = target ?? (0, proxy_target_resolver_1.getProxyTarget)();
    if (!proxyTarget.isRemote) {
        throw new Error('fetchRemoteAuthStatus called but remote mode not enabled');
    }
    const url = (0, proxy_target_resolver_1.buildProxyUrl)(proxyTarget, '/v0/management/auth-files');
    const headers = (0, proxy_target_resolver_1.buildManagementHeaders)(proxyTarget);
    try {
        const response = await fetchRemoteAuthResponse(url, headers, proxyTarget);
        if (!response.ok) {
            if (response.status === 401 || response.status === 403) {
                throw new Error('Authentication failed - check auth token in settings');
            }
            throw new Error(`Remote returned ${response.status}: ${response.statusText}`);
        }
        const data = await response.json();
        // Validate response structure
        if (!data || typeof data !== 'object' || !('files' in data) || !Array.isArray(data.files)) {
            throw new Error('Invalid response format from remote auth endpoint');
        }
        return transformRemoteAuthFiles(data.files);
    }
    catch (error) {
        if (error instanceof Error && error.name === 'AbortError') {
            throw new Error('Remote proxy connection timed out');
        }
        if (error instanceof Error && error.message === 'Request timeout') {
            throw new Error('Remote proxy connection timed out');
        }
        throw error;
    }
}
exports.fetchRemoteAuthStatus = fetchRemoteAuthStatus;
/**
 * Transform CLIProxyAPI auth files to CCS AuthStatus format
 * @param files Array of auth files from remote API
 */
function transformRemoteAuthFiles(files) {
    const byProvider = new Map();
    for (const file of files) {
        const provider = (0, provider_capabilities_1.mapExternalProviderName)(file.provider);
        if (!provider) {
            // Unknown provider, skip (could add logging in debug mode)
            continue;
        }
        const existing = byProvider.get(provider);
        if (existing) {
            existing.push(file);
        }
        else {
            byProvider.set(provider, [file]);
        }
    }
    const result = [];
    for (const [provider, providerFiles] of byProvider) {
        const activeFiles = providerFiles.filter((f) => f.status === 'active');
        const accounts = providerFiles.map((f, idx) => ({
            id: f.id,
            email: f.email || f.name || 'Unknown',
            // Keep provider on each account so UI account rendering can infer capabilities safely.
            provider,
            isDefault: idx === 0,
            status: f.status,
        }));
        result.push({
            provider,
            displayName: (0, provider_capabilities_1.getProviderDisplayName)(provider),
            authenticated: activeFiles.length > 0,
            tokenFiles: providerFiles.length,
            accounts,
            defaultAccount: accounts.find((a) => a.isDefault)?.id || null,
            source: 'remote',
        });
    }
    return result;
}
//# sourceMappingURL=remote-auth-fetcher.js.map