import path from 'path';
import fs from 'fs/promises';
import { createWriteStream } from 'fs';
import { pipeline } from 'stream/promises';
import logger from './logger.js';
const SUPPORTED_PLATFORMS = new Set(['win32', 'linux']);
const SUPPORTED_ARCHS = new Set(['x64', 'arm64']);
class PtyManager {
    constructor() {
        this.DOWNLOAD_URL = 'https://github.com/MCSManager/PTY/releases/download/latest/';
    }
    getBinaryName() {
        const platform = process.platform;
        const arch = process.arch;
        if (!SUPPORTED_PLATFORMS.has(platform)) {
            throw new Error(`不支持的操作系统平台: ${platform}`);
        }
        if (!SUPPORTED_ARCHS.has(arch)) {
            throw new Error(`不支持的 CPU 架构: ${arch}`);
        }
        const name = `pty_${platform}_${arch}`;
        return platform === 'win32' ? `${name}.exe` : name;
    }
    getLibDirCandidates() {
        const baseDir = process.cwd();
        return [
            path.join(baseDir, 'data', 'lib'),
            path.join(baseDir, 'server', 'data', 'lib'),
        ];
    }
    async getPtyPath() {
        const binaryName = this.getBinaryName();
        const candidates = this.getLibDirCandidates();
        for (const libDir of candidates) {
            const fullPath = path.join(libDir, binaryName);
            try {
                await fs.access(fullPath);
                return fullPath;
            }
            catch {
            }
        }
        throw new Error(`未找到 PTY 二进制文件 (${binaryName})，已尝试路径: ${candidates.map(d => path.join(d, binaryName)).join(', ')}`);
    }
    async isInstalled() {
        try {
            await this.getPtyPath();
            return true;
        }
        catch {
            return false;
        }
    }
    async downloadFromUrl(url, targetPath) {
        const axios = (await import('axios')).default;
        const response = await axios.get(url, {
            responseType: 'stream',
            timeout: 60000,
        });
        const writer = createWriteStream(targetPath);
        await pipeline(response.data, writer);
        const stat = await fs.stat(targetPath);
        if (stat.size === 0) {
            await fs.unlink(targetPath);
            throw new Error('下载的文件大小为 0，已删除');
        }
        if (process.platform !== 'win32') {
            await fs.chmod(targetPath, 0o755);
        }
    }
    async download() {
        const binaryName = this.getBinaryName();
        const candidates = this.getLibDirCandidates();
        let targetDir = null;
        for (const dir of candidates) {
            try {
                await fs.mkdir(dir, { recursive: true });
                targetDir = dir;
                break;
            }
            catch {
            }
        }
        if (!targetDir) {
            throw new Error(`无法创建 lib 目录，已尝试: ${candidates.join(', ')}`);
        }
        const targetPath = path.join(targetDir, binaryName);
        const downloadUrl = `${this.DOWNLOAD_URL}${binaryName}`;
        logger.info(`正在从 GitHub 下载 PTY: ${downloadUrl}`);
        try {
            await this.downloadFromUrl(downloadUrl, targetPath);
            logger.info(`PTY 下载完成: ${targetPath}`);
        }
        catch (error) {
            try {
                await fs.unlink(targetPath);
            }
            catch { }
            const message = `PTY 下载失败（GitHub）: ${error.message || error}`;
            logger.error(message);
            throw new Error(message);
        }
    }
    async ensureInstalled() {
        if (await this.isInstalled()) {
            logger.info('PTY 已存在，跳过下载');
            return;
        }
        await this.download();
    }
}
export const ptyManager = new PtyManager();
export { PtyManager };
