"use strict";
/**
 * Remote Token Uploader
 *
 * Uploads OAuth tokens to remote CLIProxyAPI server after local authentication.
 * Enables multi-device access to the same OAuth accounts.
 */
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.isRemoteUploadEnabled = exports.uploadAllTokensToRemote = exports.uploadTokenToRemote = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const proxy_target_resolver_1 = require("../proxy/proxy-target-resolver");
const ui_1 = require("../../utils/ui");
/** Timeout for upload requests (ms) */
const UPLOAD_TIMEOUT_MS = 10000;
/**
 * Upload a token file to remote CLIProxyAPI server.
 * Uses multipart/form-data as required by CLIProxyAPI.
 *
 * @param tokenFilePath - Path to local token JSON file
 * @param verbose - Enable verbose logging
 * @returns true if upload succeeded
 */
async function uploadTokenToRemote(tokenFilePath, verbose = false) {
    const target = (0, proxy_target_resolver_1.getProxyTarget)();
    if (!target.isRemote) {
        if (verbose) {
            console.error('[upload] Remote mode not enabled, skipping upload');
        }
        return false;
    }
    // Read token file
    let tokenContent;
    try {
        tokenContent = fs.readFileSync(tokenFilePath, 'utf-8');
    }
    catch (error) {
        console.error((0, ui_1.fail)(`Failed to read token file: ${error.message}`));
        return false;
    }
    // Validate JSON
    try {
        JSON.parse(tokenContent);
    }
    catch {
        console.error((0, ui_1.fail)('Invalid token file: not valid JSON'));
        return false;
    }
    const fileName = path.basename(tokenFilePath);
    const url = (0, proxy_target_resolver_1.buildProxyUrl)(target, '/v0/management/auth-files');
    // Use Authorization: Bearer header for authentication
    const authKey = target.managementKey ?? target.authToken;
    if (verbose) {
        console.error(`[upload] Uploading ${fileName} to ${target.host}`);
    }
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), UPLOAD_TIMEOUT_MS);
    try {
        // CLIProxyAPI requires multipart/form-data with "file" field
        const formData = new FormData();
        const blob = new Blob([tokenContent], { type: 'application/json' });
        formData.append('file', blob, fileName);
        const headers = {};
        if (authKey) {
            headers['Authorization'] = `Bearer ${authKey}`;
        }
        const response = await fetch(url, {
            method: 'POST',
            headers,
            body: formData,
            signal: controller.signal,
        });
        clearTimeout(timeoutId);
        if (!response.ok) {
            const text = await response.text();
            console.error((0, ui_1.fail)(`Upload failed: ${response.status} ${text}`));
            return false;
        }
        const result = (await response.json());
        if (result.status === 'ok' || result.success || result.id) {
            console.log((0, ui_1.ok)(`Token uploaded to remote server: ${fileName}`));
            return true;
        }
        else {
            console.error((0, ui_1.fail)(`Upload failed: ${result.error || result.message || 'Unknown error'}`));
            return false;
        }
    }
    catch (error) {
        clearTimeout(timeoutId);
        if (error instanceof Error && error.name === 'AbortError') {
            console.error((0, ui_1.fail)('Upload timed out'));
        }
        else {
            console.error((0, ui_1.fail)(`Upload failed: ${error.message}`));
        }
        return false;
    }
}
exports.uploadTokenToRemote = uploadTokenToRemote;
/**
 * Upload all tokens from a provider directory to remote server.
 *
 * @param tokenDir - Directory containing token files
 * @param verbose - Enable verbose logging
 * @returns Number of successfully uploaded tokens
 */
async function uploadAllTokensToRemote(tokenDir, verbose = false) {
    const target = (0, proxy_target_resolver_1.getProxyTarget)();
    if (!target.isRemote) {
        if (verbose) {
            console.error('[upload] Remote mode not enabled, skipping upload');
        }
        return 0;
    }
    if (!fs.existsSync(tokenDir)) {
        if (verbose) {
            console.error(`[upload] Token directory does not exist: ${tokenDir}`);
        }
        return 0;
    }
    const files = fs.readdirSync(tokenDir).filter((f) => f.endsWith('.json'));
    if (files.length === 0) {
        if (verbose) {
            console.error('[upload] No token files found');
        }
        return 0;
    }
    console.log((0, ui_1.info)(`Uploading ${files.length} token(s) to remote server...`));
    let uploaded = 0;
    for (const file of files) {
        const filePath = path.join(tokenDir, file);
        const success = await uploadTokenToRemote(filePath, verbose);
        if (success) {
            uploaded++;
        }
    }
    if (uploaded > 0) {
        console.log((0, ui_1.ok)(`Uploaded ${uploaded}/${files.length} token(s) to ${target.host}`));
    }
    else {
        console.log((0, ui_1.warn)('No tokens were uploaded'));
    }
    return uploaded;
}
exports.uploadAllTokensToRemote = uploadAllTokensToRemote;
/**
 * Check if remote upload is enabled and configured.
 */
function isRemoteUploadEnabled() {
    const target = (0, proxy_target_resolver_1.getProxyTarget)();
    return target.isRemote && Boolean(target.managementKey ?? target.authToken);
}
exports.isRemoteUploadEnabled = isRemoteUploadEnabled;
//# sourceMappingURL=remote-token-uploader.js.map