"use strict";
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());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.InfoAction = void 0;
const chalk = require("chalk");
const fs_1 = require("fs");
const os_1 = require("os");
const osName = require("os-name");
const path_1 = require("path");
const abstract_action_1 = require("./abstract.action");
const ui_1 = require("../lib/ui");
class InfoAction extends abstract_action_1.AbstractAction {
    handle() {
        return __awaiter(this, void 0, void 0, function* () {
            this.displayBanner();
            yield this.displaySystemInformation();
            yield this.displayMetristsInformation();
        });
    }
    displayBanner() {
        console.info(chalk.green(ui_1.BANNER));
    }
    displaySystemInformation() {
        return __awaiter(this, void 0, void 0, function* () {
            console.info(chalk.green('[System Information]'));
            console.info('OS Version     :', chalk.blue(osName((0, os_1.platform)(), (0, os_1.release)())));
            console.info('NodeJS Version :', chalk.blue(process.version));
        });
    }
    displayMetristsInformation() {
        return __awaiter(this, void 0, void 0, function* () {
            this.displayCliVersion();
            console.info(chalk.green('[Metrists Platform Information]'));
            yield this.displayMetristsInformationFromPackage();
        });
    }
    displayMetristsInformationFromPackage() {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                const dependencies = this.readProjectPackageDependencies();
                this.displayMetristsVersions(dependencies);
            }
            catch (err) {
                console.error(chalk.red(ui_1.MESSAGES.METRISTS_INFORMATION_PACKAGE_MANAGER_FAILED));
            }
        });
    }
    displayCliVersion() {
        console.info(chalk.green('[Metrists CLI]'));
        console.info('Metrists CLI Version :', chalk.blue(this.getCliPackageJson().version), '\n');
    }
    readProjectPackageDependencies() {
        const pack = this.getPackageJson();
        const dependencies = Object.assign(Object.assign({}, pack.dependencies), pack.devDependencies);
        const versionDependencies = {};
        Object.keys(dependencies).forEach((key) => {
            versionDependencies[key] = {
                version: dependencies[key],
            };
        });
        return versionDependencies;
    }
    displayMetristsVersions(dependencies) {
        this.buildMetristsVersionsMessage(dependencies).forEach((dependency) => console.info(dependency.name, chalk.blue(dependency.value)));
    }
    buildMetristsVersionsMessage(dependencies) {
        const metristsDependencies = this.collectMetristsDependencies(dependencies);
        return this.format(metristsDependencies);
    }
    collectMetristsDependencies(dependencies) {
        const metristsDependencies = [];
        Object.keys(dependencies).forEach((key) => {
            if (key.indexOf('@metrists') > -1) {
                const depPackagePath = require.resolve(key + '/package.json', {
                    paths: [process.cwd()],
                });
                const depPackage = (0, fs_1.readFileSync)(depPackagePath).toString();
                const value = JSON.parse(depPackage).version;
                metristsDependencies.push({
                    name: `${key.replace(/@metrists\//, '').replace(/@.*/, '')} version`,
                    value: value || dependencies[key].version,
                });
            }
        });
        return metristsDependencies;
    }
    format(dependencies) {
        if (!(dependencies === null || dependencies === void 0 ? void 0 : dependencies.length)) {
            return [];
        }
        const sorted = dependencies.sort((dependencyA, dependencyB) => dependencyB.name.length - dependencyA.name.length);
        const length = sorted[0].name.length;
        sorted.forEach((dependency) => {
            if (dependency.name.length < length) {
                dependency.name = this.rightPad(dependency.name, length);
            }
            dependency.name = dependency.name.concat(' :');
            dependency.value = dependency.value.replace(/(\^|\~)/, '');
        });
        return sorted;
    }
    rightPad(name, length) {
        while (name.length < length) {
            name = name.concat(' ');
        }
        return name;
    }
    getPackageJson() {
        return JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(process.cwd(), 'package.json'), 'utf8'));
    }
    getCliPackageJson() {
        return JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, '../package.json'), 'utf8'));
    }
}
exports.InfoAction = InfoAction;
