"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments)).next());
    });
};
const path = require("path");
const constants_1 = require("../constants");
class TestInitCommand {
    constructor($npm, $projectData, $errors, $options, $prompter, $fs, $resources, $pluginsService, $logger) {
        this.$npm = $npm;
        this.$projectData = $projectData;
        this.$errors = $errors;
        this.$options = $options;
        this.$prompter = $prompter;
        this.$fs = $fs;
        this.$resources = $resources;
        this.$pluginsService = $pluginsService;
        this.$logger = $logger;
        this.allowedParameters = [];
        this.frameworkDependencies = {
            mocha: ['chai'],
        };
    }
    execute(args) {
        return __awaiter(this, void 0, void 0, function* () {
            let projectDir = this.$projectData.projectDir;
            let frameworkToInstall = this.$options.framework ||
                (yield this.$prompter.promptForChoice('Select testing framework:', constants_1.TESTING_FRAMEWORKS));
            if (constants_1.TESTING_FRAMEWORKS.indexOf(frameworkToInstall) === -1) {
                this.$errors.fail(`Unknown or unsupported unit testing framework: ${frameworkToInstall}`);
            }
            let dependencies = this.frameworkDependencies[frameworkToInstall] || [];
            let modulesToInstall = ['karma', 'karma-' + frameworkToInstall, 'karma-nativescript-launcher'].concat(dependencies.map(f => 'karma-' + f));
            for (let mod of modulesToInstall) {
                yield this.$npm.install(mod, projectDir, {
                    'save-dev': true,
                    optional: false,
                });
            }
            yield this.$pluginsService.add('nativescript-unit-test-runner');
            let testsDir = path.join(projectDir, 'app/tests');
            let shouldCreateSampleTests = true;
            if (this.$fs.exists(testsDir)) {
                this.$logger.info('app/tests/ directory already exists, will not create an example test project.');
                shouldCreateSampleTests = false;
            }
            this.$fs.ensureDirectoryExists(testsDir);
            let karmaConfTemplate = this.$resources.readText('test/karma.conf.js');
            let karmaConf = _.template(karmaConfTemplate)({
                frameworks: [frameworkToInstall].concat(dependencies)
                    .map(fw => `'${fw}'`)
                    .join(', ')
            });
            this.$fs.writeFile(path.join(projectDir, 'karma.conf.js'), karmaConf);
            let exampleFilePath = this.$resources.resolvePath(`test/example.${frameworkToInstall}.js`);
            if (shouldCreateSampleTests && this.$fs.exists(exampleFilePath)) {
                this.$fs.copyFile(exampleFilePath, path.join(testsDir, 'example.js'));
                this.$logger.info('\nExample test file created in app/tests/'.yellow);
            }
            else {
                this.$logger.info('\nPlace your test files under app/tests/'.yellow);
            }
            this.$logger.info('Run your tests using the "$ tns test <platform>" command.'.yellow);
        });
    }
}
$injector.registerCommand("test|init", TestInitCommand);
