"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;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TemplateManager = void 0;
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const simple_git_1 = require("simple-git");
const error_1 = require("../error");
const BUILTIN_TEMPLATES = {
    miniprogram: {
        url: 'https://static.cloudbase.net/cloudbase-examples/miniprogram-cloudbase-miniprogram-template.zip',
        name: '微信小程序 + CloudBase'
    },
    react: {
        url: 'https://static.cloudbase.net/cloudbase-examples/web-cloudbase-react-template.zip',
        name: 'Web 应用 - React + CloudBase'
    },
    vue: {
        url: 'https://static.cloudbase.net/cloudbase-examples/web-cloudbase-vue-template.zip',
        name: 'Web 应用 - Vue + CloudBase'
    },
    uniapp: {
        url: 'https://static.cloudbase.net/cloudbase-examples/universal-cloudbase-uniapp-template.zip',
        name: '跨端应用 - UniApp + CloudBase'
    },
    rules: {
        url: 'https://static.cloudbase.net/cloudbase-examples/web-cloudbase-project.zip',
        name: 'AI 规则和配置'
    }
};
class TemplateManager {
    constructor() {
        this.git = (0, simple_git_1.simpleGit)();
    }
    pullTemplate(source, options = {}, log) {
        return __awaiter(this, void 0, void 0, function* () {
            const targetPath = options.output || process.cwd();
            yield this.checkTargetDirectory(targetPath, options.force, log);
            if (this.isBuiltinTemplate(source)) {
                yield this.downloadBuiltinTemplate(source, targetPath, log);
            }
            else if (this.isGitUrl(source)) {
                const gitInfo = this.parseGitUrl(source);
                yield this.downloadGitTemplate(gitInfo, targetPath, log);
            }
            else {
                throw new error_1.CloudBaseError(`不支持的模板来源: ${typeof source === 'string' ? source : JSON.stringify(source)}`);
            }
        });
    }
    isBuiltinTemplate(source) {
        return Object.keys(BUILTIN_TEMPLATES).includes(source);
    }
    isGitUrl(source) {
        if (!source || typeof source !== 'string') {
            return false;
        }
        return source.startsWith('http') || source.startsWith('git@') || source.includes('github.com') || source.includes('gitee.com');
    }
    downloadBuiltinTemplate(templateId, targetPath, log) {
        return __awaiter(this, void 0, void 0, function* () {
            const template = BUILTIN_TEMPLATES[templateId];
            if (!template) {
                throw new error_1.CloudBaseError(`未知的内置模板: ${templateId}`);
            }
            log.info(`📦 正在下载 ${template.name} 模板...`);
            try {
                const { downloadAndExtractRemoteZip } = yield Promise.resolve().then(() => __importStar(require('./tools/common')));
                yield downloadAndExtractRemoteZip(template.url, targetPath);
                log.info(`✅ ${template.name} 模板下载完成`);
            }
            catch (error) {
                throw new error_1.CloudBaseError(`下载模板失败: ${error.message}`, { original: error });
            }
        });
    }
    downloadGitTemplate(gitInfo, targetPath, log) {
        return __awaiter(this, void 0, void 0, function* () {
            const gitUrl = this.buildGitUrl(gitInfo);
            log.info(`📦 正在从 ${gitInfo.platform} 下载模板...`);
            try {
                if (gitInfo.subpath) {
                    yield this.cloneWithSubpath(gitUrl, targetPath, gitInfo, log);
                }
                else {
                    yield this.cloneFull(gitUrl, targetPath, log);
                }
                log.info(`✅ Git 模板下载完成`);
            }
            catch (error) {
                throw new error_1.CloudBaseError(`Git 模板下载失败: ${error.message}`, { original: error });
            }
        });
    }
    parseGitUrl(url) {
        const githubMatch = url.match(/https?:\/\/github\.com\/([^\/]+)\/([^\/]+)(?:\/tree\/([^\/]+)\/(.+))?/);
        if (githubMatch) {
            return {
                platform: 'github',
                owner: githubMatch[1],
                repo: githubMatch[2].replace('.git', ''),
                branch: githubMatch[3] || 'master',
                subpath: githubMatch[4]
            };
        }
        const giteeMatch = url.match(/https?:\/\/gitee\.com\/([^\/]+)\/([^\/]+)(?:\/tree\/([^\/]+)\/(.+))?/);
        if (giteeMatch) {
            return {
                platform: 'gitee',
                owner: giteeMatch[1],
                repo: giteeMatch[2].replace('.git', ''),
                branch: giteeMatch[3] || 'master',
                subpath: giteeMatch[4]
            };
        }
        const sshMatch = url.match(/git@([^:]+):([^\/]+)\/([^\/]+)\.git/);
        if (sshMatch) {
            return {
                platform: sshMatch[1] === 'github.com' ? 'github' : 'gitee',
                owner: sshMatch[2],
                repo: sshMatch[3],
                branch: 'main'
            };
        }
        throw new error_1.CloudBaseError(`无法解析 Git URL: ${url}`);
    }
    buildGitUrl(gitInfo) {
        if (gitInfo.platform === 'github') {
            return `https://github.com/${gitInfo.owner}/${gitInfo.repo}.git`;
        }
        else if (gitInfo.platform === 'gitee') {
            return `https://gitee.com/${gitInfo.owner}/${gitInfo.repo}.git`;
        }
        throw new error_1.CloudBaseError(`不支持的 Git 平台: ${gitInfo.platform}`);
    }
    cloneFull(gitUrl, targetPath, log) {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                yield this.git.clone(gitUrl, targetPath);
            }
            catch (error) {
                throw new error_1.CloudBaseError(`克隆仓库失败: ${error.message}`, { original: error });
            }
        });
    }
    cloneWithSubpath(gitUrl, targetPath, gitInfo, log) {
        return __awaiter(this, void 0, void 0, function* () {
            const tempDir = path_1.default.join(process.cwd(), '.temp-clone-' + Date.now());
            try {
                yield this.git.clone(gitUrl, tempDir);
                const tempGit = (0, simple_git_1.simpleGit)(tempDir);
                yield tempGit.checkout(gitInfo.branch);
                const subpathFull = path_1.default.join(tempDir, gitInfo.subpath);
                if (!(yield fs_extra_1.default.pathExists(subpathFull))) {
                    throw new error_1.CloudBaseError(`子目录不存在: ${gitInfo.subpath}`);
                }
                yield fs_extra_1.default.copy(subpathFull, targetPath);
            }
            finally {
                yield fs_extra_1.default.remove(tempDir);
            }
        });
    }
    checkTargetDirectory(targetPath, force = false, log) {
        return __awaiter(this, void 0, void 0, function* () {
            if (yield fs_extra_1.default.pathExists(targetPath)) {
                const files = yield fs_extra_1.default.readdir(targetPath);
                if (files.length > 0) {
                    if (!force) {
                        const inquirer = yield Promise.resolve().then(() => __importStar(require('inquirer')));
                        const { confirm } = yield inquirer.prompt([
                            {
                                type: 'confirm',
                                name: 'confirm',
                                message: `目标目录 ${targetPath} 不为空，是否覆盖？`,
                                default: false
                            }
                        ]);
                        if (!confirm) {
                            throw new error_1.CloudBaseError('操作已取消');
                        }
                    }
                    log.info(`🗑️  清理目标目录: ${targetPath}`);
                    yield fs_extra_1.default.remove(targetPath);
                }
            }
            yield fs_extra_1.default.ensureDir(targetPath);
        });
    }
    getBuiltinTemplates() {
        const templates = {};
        for (const [key, template] of Object.entries(BUILTIN_TEMPLATES)) {
            templates[key] = template.name;
        }
        return templates;
    }
}
exports.TemplateManager = TemplateManager;
