"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
require("es6-promise/auto");
var chalk = require("chalk");
var memFs = require("mem-fs");
var fsEditor = require("mem-fs-editor");
var emoji = require("node-emoji");
var ProgressBar = require("progress");
var immutable_1 = require("immutable");
// This monkeypatch is necessary for for–await-of to work in Typescript v2.4+
Symbol.asyncIterator =
    Symbol.asyncIterator || Symbol.for("Symbol.asyncIterator");
var Migrator = (function () {
    function Migrator() {
        this.progressBar = new ProgressBar(" [:bar] " + chalk.bold(":current/:total") + " steps complete", {
            total: Migrator.steps.size - 1,
            complete: chalk.bold.green("="),
            incomplete: chalk.green("-"),
            width: 20
        });
    }
    Migrator.prototype.perform = function (options) {
        return tslib_1.__asyncGenerator(this, arguments, function perform_1() {
            var _a, _b, stepName, step, newOptions, e_1_1, e_1, _c;
            return tslib_1.__generator(this, function (_d) {
                switch (_d.label) {
                    case 0:
                        _d.trys.push([0, 6, 7, 8]);
                        _a = tslib_1.__values(Migrator.steps), _b = _a.next();
                        _d.label = 1;
                    case 1:
                        if (!!_b.done) return [3 /*break*/, 5];
                        stepName = _b.value;
                        options = options.set("step", stepName);
                        step = require("./steps/" + stepName).default;
                        return [4 /*yield*/, tslib_1.__await(step(options))];
                    case 2:
                        newOptions = _d.sent();
                        options = options.merge(newOptions);
                        return [4 /*yield*/, options];
                    case 3:
                        _d.sent();
                        _d.label = 4;
                    case 4:
                        _b = _a.next();
                        return [3 /*break*/, 1];
                    case 5: return [3 /*break*/, 8];
                    case 6:
                        e_1_1 = _d.sent();
                        e_1 = { error: e_1_1 };
                        return [3 /*break*/, 8];
                    case 7:
                        try {
                            if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
                        }
                        finally { if (e_1) throw e_1.error; }
                        return [7 /*endfinally*/];
                    case 8: return [2 /*return*/];
                }
            });
        });
    };
    Migrator.migrate = function (cliOptions) {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var store, editor, migratr, options, _a, _b, newOptions, e_2_1, err_1, e_2, _c;
            return tslib_1.__generator(this, function (_d) {
                switch (_d.label) {
                    case 0:
                        store = memFs.create();
                        editor = fsEditor.create(store);
                        migratr = new Migrator();
                        options = immutable_1.Map({
                            editor: editor
                        }).merge(cliOptions);
                        _d.label = 1;
                    case 1:
                        _d.trys.push([1, 15, , 16]);
                        _d.label = 2;
                    case 2:
                        _d.trys.push([2, 8, 9, 14]);
                        _a = tslib_1.__asyncValues(migratr.perform(options));
                        _d.label = 3;
                    case 3: return [4 /*yield*/, _a.next()];
                    case 4:
                        if (!(_b = _d.sent(), !_b.done)) return [3 /*break*/, 7];
                        return [4 /*yield*/, _b.value];
                    case 5:
                        newOptions = _d.sent();
                        if (!migratr.progressBar.complete)
                            migratr.progressBar.tick();
                        _d.label = 6;
                    case 6: return [3 /*break*/, 3];
                    case 7: return [3 /*break*/, 14];
                    case 8:
                        e_2_1 = _d.sent();
                        e_2 = { error: e_2_1 };
                        return [3 /*break*/, 14];
                    case 9:
                        _d.trys.push([9, , 12, 13]);
                        if (!(_b && !_b.done && (_c = _a.return))) return [3 /*break*/, 11];
                        return [4 /*yield*/, _c.call(_a)];
                    case 10:
                        _d.sent();
                        _d.label = 11;
                    case 11: return [3 /*break*/, 13];
                    case 12:
                        if (e_2) throw e_2.error;
                        return [7 /*endfinally*/];
                    case 13: return [7 /*endfinally*/];
                    case 14:
                        console.log(chalk.bold.green(emoji.emojify("Finished all steps! :rocket:")));
                        return [3 /*break*/, 16];
                    case 15:
                        err_1 = _d.sent();
                        migratr.progressBar.interrupt(chalk.bold.red(err_1.message));
                        return [3 /*break*/, 16];
                    case 16: return [2 /*return*/];
                }
            });
        });
    };
    Migrator.steps = immutable_1.List([
        "setup_paths",
        "correct_version",
        "marketing_only",
        "requirements_only",
        "setup_app_scaffold",
        "migrate_common_js",
        "migrate_app_js",
        "migrate_app_css",
        "migrate_templates",
        "migrate_translations",
        "migrate_images",
        "migrate_manifest",
        "commit_changes",
        "run_scripts"
    ]);
    return Migrator;
}());
exports.default = Migrator;
