"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.main = exports.promptDestination = exports.getDestination = exports.parseArgs = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importStar(require("path"));
const chalk_1 = __importDefault(require("chalk"));
const inquirer_1 = __importDefault(require("inquirer"));
const init_runner_1 = require("./init-runner");
const minimist_1 = __importDefault(require("minimist"));
const common_1 = require("./common");
const parseArgs = () => {
    // parse any command line arguments passed into `init sitecore-jss`
    // to pass to the generator prompts and skip them.
    // useful for CI and testing purposes
    const options = {
        boolean: ['appPrefix', 'force', 'noInstall', 'yes', 'silent', 'prePushHook'],
        string: [
            'appName',
            'destination',
            'proxyAppDestination',
            'templates',
            'hostName',
            'fetchWith',
            'language',
        ],
        default: { prePushHook: null },
    };
    const args = (0, minimist_1.default)(process.argv.slice(2), options);
    // we need to coerce string parameters in minimist above (to prevent string options without a value e.g. `--appName` from coming in as a boolean `true`).
    // however, coersion will result in an empty string and inquirer will treat this as a valid answer value (and not prompt!).
    // we need to go back through and remove these to prevent this.
    options.string.forEach((key) => {
        args[key] === '' && delete args[key];
    });
    return args;
};
exports.parseArgs = parseArgs;
const getDestination = (args, templates) => __awaiter(void 0, void 0, void 0, function* () {
    if (templates.length === 0) {
        throw new Error('Unable to get destinations, provided templates are empty');
    }
    // validate/gather destinations
    const defaultBaseDestination = `${process.cwd()}${args.appName ? path_1.sep + args.appName : `${path_1.sep}${templates[0]}`}`;
    let destination = args.destination;
    if (!destination) {
        destination = args.yes
            ? defaultBaseDestination
            : yield (0, exports.promptDestination)('Where would you like your new app created?', defaultBaseDestination);
    }
    return destination;
});
exports.getDestination = getDestination;
const promptDestination = (prompt, defaultDestination) => __awaiter(void 0, void 0, void 0, function* () {
    return (yield inquirer_1.default.prompt({
        type: 'input',
        name: 'destination',
        message: prompt,
        default: () => defaultDestination,
    })).destination;
});
exports.promptDestination = promptDestination;
const main = (args) => __awaiter(void 0, void 0, void 0, function* () {
    let templates = [];
    // check if templates were provided
    if (args._.length > 0 && args._[0] !== undefined) {
        // use positional parameter
        templates = (args._[0] && args._[0].split(/[\s,]+/)) || [];
    }
    else {
        // use --templates arg
        templates = (args.templates && args.templates.split(/[\s,]+/)) || [];
    }
    // validate/gather templates
    const templatePath = path_1.default.resolve(__dirname, 'templates');
    if (templates.length > 0) {
        const allTemplates = (0, common_1.getAllTemplates)(templatePath);
        const validTemplates = [];
        templates.forEach((template) => {
            if (allTemplates.includes(template)) {
                validTemplates.push(template);
            }
            else {
                console.log(chalk_1.default.yellow(`Ignoring unknown template '${template}'...`));
            }
        });
        templates = validTemplates;
    }
    if (!templates.length) {
        const baseTemplates = yield (0, common_1.getBaseTemplates)(templatePath);
        const answer = yield inquirer_1.default.prompt({
            type: 'list',
            name: 'template',
            message: 'Which template would you like to create?',
            choices: baseTemplates,
            default: 'nextjs',
        });
        templates.push(answer.template);
    }
    const destination = yield (0, exports.getDestination)(args, templates);
    if (!args.force && fs_1.default.existsSync(destination) && fs_1.default.readdirSync(destination).length > 0) {
        const answer = yield inquirer_1.default.prompt({
            type: 'confirm',
            name: 'continue',
            message: `Directory '${destination}' not empty. Are you sure you want to continue?`,
        });
        if (!answer.continue) {
            process.exit();
        }
    }
    else {
        args.force = true;
    }
    if (!args.yes) {
        if (args.prePushHook === null) {
            const answer = yield inquirer_1.default.prompt({
                type: 'confirm',
                name: 'prePushHook',
                message: 'Would you like to use the pre-push hook for linting check?',
                default: false,
            });
            args.prePushHook = answer.prePushHook;
        }
    }
    else {
        if (args.prePushHook === null) {
            args.prePushHook = false;
        }
    }
    try {
        yield (0, init_runner_1.initRunner)(templates.slice(), Object.assign(Object.assign({}, args), { destination, templates }));
    }
    catch (error) {
        console.log(chalk_1.default.red('An error occurred: ', error));
        process.exit(1);
    }
});
exports.main = main;
