"use strict";
/**
 * Clone Starter Command
 *
 * Clones the admin starter repository and sets up the project
 * with InstantDB, shadcn/ui, and authentication.
 */
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 () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CloneStarterCommand = void 0;
const commander_1 = require("commander");
const fs = __importStar(require("fs/promises"));
const path = __importStar(require("path"));
const child_process_1 = require("child_process");
const util_1 = require("util");
const chalk_1 = __importDefault(require("chalk"));
const execAsync = (0, util_1.promisify)(child_process_1.exec);
class CloneStarterCommand {
    constructor() {
        this.command = new commander_1.Command("clone-starter");
        this.setupCommand();
    }
    setupCommand() {
        this.command
            .description("Clone admin starter repository and set up project")
            .option("--url <url>", "GitHub repository URL", "https://github.com/mycontext/admin-starter")
            .option("--output <path>", "Output directory for cloned project", "./admin-starter")
            .option("--branch <branch>", "Git branch to clone", "main")
            .option("--install", "Install dependencies after cloning", true)
            .option("--setup", "Run setup commands after cloning", true)
            .option("--verbose", "Verbose output")
            .action(async (options) => {
            await this.execute(options);
        });
    }
    async execute(options) {
        console.log(chalk_1.default.cyan("📦 Cloning admin starter..."));
        try {
            const outputPath = path.resolve(options.output || "./admin-starter");
            // Step 1: Clone repository
            console.log(chalk_1.default.gray("  📥 Cloning repository..."));
            await this.cloneRepository(options.url, outputPath, options.branch);
            // Step 2: Load starter bundle configuration
            console.log(chalk_1.default.gray("  📋 Loading starter configuration..."));
            const starterBundle = await this.loadStarterBundle();
            // Step 3: Install dependencies
            if (options.install) {
                console.log(chalk_1.default.gray("  📦 Installing dependencies..."));
                await this.installDependencies(outputPath);
            }
            // Step 4: Set up environment
            console.log(chalk_1.default.gray("  ⚙️  Setting up environment..."));
            await this.setupEnvironment(outputPath, starterBundle);
            // Step 5: Run setup commands
            if (options.setup) {
                console.log(chalk_1.default.gray("  🔧 Running setup commands..."));
                await this.runSetupCommands(outputPath, starterBundle);
            }
            // Step 6: Save starter configuration
            console.log(chalk_1.default.gray("  💾 Saving starter configuration..."));
            await this.saveStarterConfiguration(outputPath, starterBundle);
            console.log(chalk_1.default.green("✅ Admin starter cloned and set up successfully!"));
            this.showNextSteps(outputPath, starterBundle);
        }
        catch (error) {
            console.log(chalk_1.default.red(`❌ Failed to clone starter: ${error}`));
            process.exit(1);
        }
    }
    async cloneRepository(url, outputPath, branch) {
        try {
            const command = `git clone -b ${branch} ${url} ${outputPath}`;
            await execAsync(command);
            console.log(chalk_1.default.green(`    ✓ Repository cloned to ${outputPath}`));
        }
        catch (error) {
            throw new Error(`Failed to clone repository: ${error}`);
        }
    }
    async loadStarterBundle() {
        const bundlePath = path.join(__dirname, "../../templates/admin-starter-bundle.json");
        const bundleContent = await fs.readFile(bundlePath, "utf-8");
        return JSON.parse(bundleContent);
    }
    async installDependencies(outputPath) {
        try {
            await execAsync("npm install", { cwd: outputPath });
            console.log(chalk_1.default.green("    ✓ Dependencies installed"));
        }
        catch (error) {
            console.log(chalk_1.default.yellow(`    ⚠️  Failed to install dependencies: ${error}`));
            console.log(chalk_1.default.gray('    Run "npm install" manually in the project directory'));
        }
    }
    async setupEnvironment(outputPath, starterBundle) {
        const envPath = path.join(outputPath, ".env.local");
        const envExamplePath = path.join(outputPath, ".env.example");
        // Create .env.local from .env.example if it exists
        try {
            const envExample = await fs.readFile(envExamplePath, "utf-8");
            await fs.writeFile(envPath, envExample);
            console.log(chalk_1.default.green("    ✓ Environment file created"));
        }
        catch {
            // Create basic .env.local
            const envContent = this.generateEnvironmentFile(starterBundle);
            await fs.writeFile(envPath, envContent);
            console.log(chalk_1.default.green("    ✓ Environment file created"));
        }
        // Update package.json with starter bundle info
        await this.updatePackageJson(outputPath, starterBundle);
    }
    generateEnvironmentFile(starterBundle) {
        const envVars = starterBundle.setup.environment;
        return (Object.entries(envVars)
            .map(([key, value]) => `${key}=${value}`)
            .join("\n") + "\n");
    }
    async updatePackageJson(outputPath, starterBundle) {
        const packageJsonPath = path.join(outputPath, "package.json");
        try {
            const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf-8"));
            // Add starter bundle metadata
            packageJson.mycontext = {
                starter: starterBundle.name,
                version: starterBundle.version,
                features: starterBundle.features,
                stack: starterBundle.stack,
            };
            await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
            console.log(chalk_1.default.green("    ✓ Package.json updated"));
        }
        catch (error) {
            console.log(chalk_1.default.yellow(`    ⚠️  Failed to update package.json: ${error}`));
        }
    }
    async runSetupCommands(outputPath, starterBundle) {
        for (const command of starterBundle.setup.commands) {
            try {
                console.log(chalk_1.default.gray(`    Running: ${command}`));
                await execAsync(command, { cwd: outputPath });
                console.log(chalk_1.default.green(`    ✓ ${command}`));
            }
            catch (error) {
                console.log(chalk_1.default.yellow(`    ⚠️  Failed to run "${command}": ${error}`));
            }
        }
    }
    async saveStarterConfiguration(outputPath, starterBundle) {
        const mycontextDir = path.join(outputPath, ".mycontext");
        await fs.mkdir(mycontextDir, { recursive: true });
        const configPath = path.join(mycontextDir, "admin-starter.json");
        await fs.writeFile(configPath, JSON.stringify(starterBundle, null, 2));
        console.log(chalk_1.default.green("    ✓ Starter configuration saved"));
    }
    showNextSteps(outputPath, starterBundle) {
        console.log(chalk_1.default.blue("\n📋 Next Steps:"));
        console.log(chalk_1.default.cyan("  1. Navigate to project:"));
        console.log(chalk_1.default.white(`     cd ${outputPath}`));
        console.log(chalk_1.default.cyan("  2. Configure environment:"));
        console.log(chalk_1.default.white("     # Edit .env.local with your API keys"));
        console.log(chalk_1.default.cyan("  3. Set up database:"));
        console.log(chalk_1.default.white("     mycontext setup-database"));
        console.log(chalk_1.default.cyan("  4. Start development:"));
        console.log(chalk_1.default.white("     npm run dev"));
        console.log(chalk_1.default.gray("\n  Features included:"));
        starterBundle.features.forEach((feature) => {
            console.log(chalk_1.default.gray(`  • ${feature}`));
        });
        console.log(chalk_1.default.gray("\n  Stack:"));
        Object.entries(starterBundle.stack).forEach(([key, value]) => {
            console.log(chalk_1.default.gray(`  • ${key}: ${value}`));
        });
        console.log(chalk_1.default.blue("\n🚀 Ready to build!"));
        console.log(chalk_1.default.gray("  The admin starter includes authentication, user management,"));
        console.log(chalk_1.default.gray("  and invite system. Customize it for your needs."));
    }
    getCommand() {
        return this.command;
    }
}
exports.CloneStarterCommand = CloneStarterCommand;
//# sourceMappingURL=clone-starter.js.map