"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.removeFile = exports.writeFileToPath = exports.getAppPrefix = exports.getBaseTemplates = exports.getAllTemplates = exports.sortKeys = exports.saveConfiguration = exports.writeJsonFile = exports.openJsonFile = exports.getPascalCaseName = exports.isDevEnvironment = exports.getRelativeProxyDestination = exports.getDefaultProxyDestination = exports.proxyAppMatcher = void 0;
const chalk_1 = __importDefault(require("chalk"));
const fs_1 = __importDefault(require("fs"));
const path_1 = __importStar(require("path"));
const InitializerFactory_1 = require("../../InitializerFactory");
// matched for proxy templates
exports.proxyAppMatcher = /node-headless.+|node-xmcloud.+/g;
/**
 * Returns the default path for proxy app initialized alongside main JSS tempalates.
 * @param {string} mainAppDestination target destination for main app
 * @param {string} proxyName name of for the proxy app folder
 * @returns {string} target path for proxy app
 */
const getDefaultProxyDestination = (mainAppDestination, proxyName) => path_1.default.join(mainAppDestination, '..', proxyName);
exports.getDefaultProxyDestination = getDefaultProxyDestination;
const getRelativeProxyDestination = (mainDestination, proxyDestination) => `${path_1.default.relative(path_1.default.resolve(mainDestination), path_1.default.resolve(proxyDestination))}${path_1.sep}`;
exports.getRelativeProxyDestination = getRelativeProxyDestination;
/**
 * Determines whether you are in a dev environment.
 * It's `true` if you are inside the monorepo
 * @param {string} [cwd] path to the current working directory
 * @returns {boolean} is a development environment
 */
const isDevEnvironment = (cwd) => {
    const currentPath = path_1.default.resolve(cwd || process.cwd());
    // TODO: is there a better way to detect this?
    const lernaPath = path_1.default.join(currentPath, '..', '..');
    return fs_1.default.existsSync(path_1.default.join(lernaPath, 'lerna.json'));
};
exports.isDevEnvironment = isDevEnvironment;
const getPascalCaseName = (name) => {
    // handle underscores by converting them to hyphens
    const temp = name.replace(/_/g, '-').split('-');
    name = temp.map((item) => (item = item.charAt(0).toUpperCase() + item.slice(1))).join('');
    return name;
};
exports.getPascalCaseName = getPascalCaseName;
/**
 * Provides json data from a file
 * @param {string} jsonFilePath path to the .json file.
 * @returns json data
 */
const openJsonFile = (jsonFilePath) => {
    try {
        const data = fs_1.default.readFileSync(jsonFilePath, 'utf8');
        return data ? JSON.parse(data) : undefined;
    }
    catch (error) {
        console.log(chalk_1.default.red(`The following error occurred while trying to read ${jsonFilePath}:`));
        console.log(chalk_1.default.red(error));
    }
};
exports.openJsonFile = openJsonFile;
/**
 * Creates a .json file and inserts provided data
 * @param {object} data data to be written into the .json file
 * @param {string} jsonFilePath a path to a file.
 */
const writeJsonFile = (data, jsonFilePath) => {
    try {
        fs_1.default.writeFileSync(jsonFilePath, JSON.stringify(data, null, 2), { encoding: 'utf8' });
    }
    catch (error) {
        console.log(chalk_1.default.red(`The following error occurred while trying to write ${jsonFilePath}:`));
        console.log(chalk_1.default.red(error));
    }
};
exports.writeJsonFile = writeJsonFile;
/**
 * Save configuration params to the package.json
 * @param {string[]} templates templates applied to the sample
 * @param {string} [pkgPath] path to the package.json
 */
const saveConfiguration = (templates, pkgPath) => {
    const pkg = (0, exports.openJsonFile)(pkgPath);
    (0, exports.writeJsonFile)(Object.assign(Object.assign({}, pkg), { config: Object.assign(Object.assign({}, pkg.config), { templates }) }), pkgPath);
};
exports.saveConfiguration = saveConfiguration;
const sortKeys = (obj) => {
    const sorted = {};
    Object.keys(obj)
        .sort()
        .forEach((key) => (sorted[key] = obj[key]));
    return sorted;
};
exports.sortKeys = sortKeys;
/**
 * Returns all templates
 * @param {string} templatePath path to the templates
 * @returns {string[]} templates
 */
const getAllTemplates = (templatePath) => {
    return fs_1.default.readdirSync(templatePath, 'utf8');
};
exports.getAllTemplates = getAllTemplates;
/**
 * Returns subset of base templates
 * @param {string} templatePath path to the templates
 * @returns {string[]} base templates
 */
const getBaseTemplates = (templatePath) => __awaiter(void 0, void 0, void 0, function* () {
    const templates = fs_1.default.readdirSync(templatePath, 'utf8');
    const initFactory = new InitializerFactory_1.InitializerFactory();
    const baseTemplates = [];
    for (const template of templates) {
        const res = yield initFactory.create(template);
        (res === null || res === void 0 ? void 0 : res.isBase) && baseTemplates.push(template);
    }
    return baseTemplates;
});
exports.getBaseTemplates = getBaseTemplates;
const getAppPrefix = (appPrefix, appName, includeHyphen = true) => appPrefix ? `${(0, exports.getPascalCaseName)(appName)}${includeHyphen ? '-' : ''}` : '';
exports.getAppPrefix = getAppPrefix;
const writeFileToPath = (destinationPath, content) => {
    fs_1.default.writeFileSync(destinationPath, content, 'utf8');
};
exports.writeFileToPath = writeFileToPath;
const removeFile = (filePath) => {
    fs_1.default.unlinkSync(filePath);
};
exports.removeFile = removeFile;
