"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());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __spreadArrays = (this && this.__spreadArrays) || function () {
    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
    for (var r = Array(s), k = 0, i = 0; i < il; i++)
        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
            r[k] = a[j];
    return r;
};
Object.defineProperty(exports, "__esModule", { value: true });
var inquirer = require('inquirer');
var dic_1 = require("../util/dic");
var conf = require(dic_1.ROOT_PACKAGE_PATH('src/config.json'));
var path = require('path');
var fs = require('fs');
var copy = require('copy');
//const createPkgDeclare = require('./createPkgDeclare');
var t = require('@babel/types');
var parse = require('@babel/parser').parse;
var traverse = require('@babel/traverse').default;
var generate = require('@babel/generator').default;
var PKGS = 'packages';
var emptyLine = '/*hr*/';
var nutMainFile = dic_1.ROOT_PACKAGE_PATH('src/nutui.js');
var nutTypings = dic_1.ROOT_PACKAGE_PATH('types/nutui.d.ts');
var sorts = __spreadArrays(conf.sorts);
var newCpt = {
    version: '1.0.0',
    name: '',
    type: '',
    chnName: '',
    desc: '',
    sort: '',
    showDemo: true,
    author: '',
    star: undefined,
};
function init() {
    inquirer
        .prompt([
        {
            type: 'input',
            name: 'name',
            message: '组件英文名(每个单词的首字母都大写，如TextBox)：',
            validate: function (value) {
                var repeat = conf.packages.find(function (item) {
                    return item.name === value;
                });
                if (repeat) {
                    return '该组件名已存在！';
                }
                var pass = value && value.match(/^[A-Z]/);
                if (pass) {
                    return true;
                }
                return '不能为空，且每个单词的首字母都要大写，如TextBox';
            },
        },
        {
            type: 'input',
            name: 'chnName',
            message: '组件中文名(十个字以内)：',
            validate: function (value) {
                var pass = value && value.length <= 10;
                if (pass) {
                    return true;
                }
                return '不能为空，且不能超过十个字符';
            },
        },
        {
            type: 'input',
            name: 'desc',
            message: '组件描述(五十个字以内)：',
        },
        {
            type: 'rawlist',
            name: 'type',
            message: '请选择组件类型(输入编号)：',
            choices: ['component', 'filter', 'directive', 'method'],
            validate: function (value) {
                var pass = value && /^[1-4]$/.test(value);
                if (pass) {
                    return true;
                }
                return '输入有误！请输入选项前编号';
            },
        },
        {
            type: 'rawlist',
            name: 'sort',
            message: '请选择组件分类(输入编号)：',
            choices: sorts,
            validate: function (value) {
                var pass = /^[1-7]$/.test(value);
                if (pass) {
                    return true;
                }
                return '输入有误！请输入选项前编号';
            },
        },
        {
            type: 'confirm',
            name: 'showDemo',
            message: '是否需要DEMO页面?',
            default: true,
        },
        {
            type: 'confirm',
            name: 'showTest',
            message: '是否需要单元测试页面?',
            default: true,
        },
        {
            type: 'input',
            name: 'author',
            message: '组件作者(可署化名):',
        },
    ])
        .then(function (answers) {
        answers.sort = String(sorts.indexOf(answers.sort));
        newCpt = Object.assign(newCpt, answers);
        createDir();
    });
}
function createVue() {
    return new Promise(function (resolve, reject) {
        var nameLc = newCpt.name.toLowerCase();
        var content = "<template>\n    <div class=\"nut-" + nameLc + "\"></div>\n</template>\n<script>\nexport default {\n    name:'nut-" + nameLc + "',\n    props: {\n    },\n    data() {\n        return {};\n    },\n    methods: {\n    }\n}\n</script>";
        var dirPath = path.join(dic_1.ROOT_PACKAGE_PATH('src/packages/' + nameLc));
        var filePath = path.join(dirPath, nameLc + ".vue");
        if (!fs.existsSync(dirPath)) {
            fs.mkdirSync(dirPath);
        }
        fs.writeFile(filePath, content, function (err) {
            if (err)
                throw err;
            resolve("\u751F\u6210" + newCpt.name + ".vue\u6587\u4EF6\u6210\u529F");
        });
    });
}
function createDemo() {
    return new Promise(function (resolve, reject) {
        var nameLc = newCpt.name.toLowerCase();
        var content = "<template>\n    <div class=\"demo-list\"></div>\n</template>\n<script>\nexport default {\n    data() {\n        return {};\n    },\n    methods: {\n    }\n}\n</script>";
        var dirPath = path.join(dic_1.ROOT_PACKAGE_PATH('src/packages/' + nameLc));
        var filePath = path.join(dirPath, "demo.vue");
        if (!fs.existsSync(dirPath)) {
            fs.mkdirSync(dirPath);
        }
        fs.writeFile(filePath, content, function (err) {
            if (err)
                throw err;
            resolve("\u751F\u6210demo.vue\u6587\u4EF6\u6210\u529F");
        });
    });
}
function createTest() {
    return new Promise(function (resolve, reject) {
        var nameLc = newCpt.name.toLowerCase();
        var content = "import { shallowMount, mount } from '@vue/test-utils'\nimport " + newCpt.name + " from '../" + nameLc + ".vue';\nimport Vue from 'vue';\n\t\t\ndescribe('" + newCpt.name + ".vue', () => {\n\t\t\t\n});";
        var dirPath = path.join(dic_1.ROOT_PACKAGE_PATH('src/packages/' + nameLc + '/__test__'));
        var filePath = path.join(dirPath, nameLc + ".spec.js");
        if (!fs.existsSync(dirPath)) {
            fs.mkdirSync(dirPath);
        }
        fs.writeFile(filePath, content, function (err) {
            if (err)
                throw err;
            resolve("\u751F\u6210test\u6587\u4EF6\u6210\u529F");
        });
    });
}
function createDoc() {
    return new Promise(function (resolve, reject) {
        var nameLc = newCpt.name.toLowerCase();
        var content = "" + nameLc;
        var dirPath = path.join(dic_1.ROOT_PACKAGE_PATH('src/packages/' + nameLc));
        var filePath = path.join(dirPath, "doc.md");
        if (!fs.existsSync(dirPath)) {
            fs.mkdirSync(dirPath);
        }
        fs.writeFile(filePath, content, function (err) {
            if (err)
                throw err;
            resolve("\u751F\u6210" + newCpt.name + ".doc\u6587\u4EF6\u6210\u529F");
        });
    });
}
function createScss() {
    return new Promise(function (resolve, reject) {
        var nameLc = newCpt.name.toLowerCase();
        var content = ".nut-" + nameLc + "{\n\n}";
        var dirPath = path.join(dic_1.ROOT_PACKAGE_PATH('src/packages/' + nameLc));
        var filePath = path.join(dirPath, nameLc + ".scss");
        if (!fs.existsSync(dirPath)) {
            fs.mkdirSync(dirPath);
        }
        fs.writeFile(filePath, content, function (err) {
            if (err)
                throw err;
            resolve("\u751F\u6210" + newCpt.name + ".scss\u6587\u4EF6\u6210\u529F");
        });
    });
}
function createDir() {
    var nameLc = newCpt.name.toLowerCase();
    var destPath = path.join(dic_1.ROOT_PACKAGE_PATH('src/packages/' + nameLc));
    if (!fs.existsSync(destPath)) {
        fs.mkdirSync(destPath);
    }
    copy(path.join(__dirname, './__template__/**.*'), destPath, function (err, file) {
        if (err) {
            console.log('拷贝__template__目录失败！');
        }
        createNew();
    });
}
function addToPackageJson() {
    return new Promise(function (resolve, reject) {
        conf.packages.push(newCpt);
        var dirPath = path.join(dic_1.ROOT_PACKAGE_PATH('src/'));
        var filePath = path.join(dirPath, "config.json");
        fs.writeFile(filePath, JSON.stringify(conf, null, 2), function (err) {
            if (err)
                throw err;
            resolve("\u4FEE\u6539config.json\u6587\u4EF6\u6210\u529F");
        });
    });
}
function transformCodes(codes, visitor) {
    var ast = parse(codes, {
        sourceType: 'module',
    });
    traverse(ast, visitor);
    var code = generate(ast, {
    /* options */
    }, codes).code;
    return code;
}
function createProp(pkg) {
    return t.objectProperty(t.identifier(pkg), t.identifier(pkg));
}
function addPkgDeclare(pkg) {
    var codes = fs.readFileSync(nutMainFile).toString();
    var visitor = {
        VariableDeclaration: function (p) {
            var node = p.node; //console.log(Object.keys(p.__proto__))
            if (node) {
                var _a = node.declarations, declarations = _a === void 0 ? [] : _a;
                if (declarations.length) {
                    for (var _i = 0, declarations_1 = declarations; _i < declarations_1.length; _i++) {
                        var _b = declarations_1[_i], id = _b.id, init_1 = _b.init;
                        if (id.name === PKGS && init_1.properties && init_1.properties.length) {
                            var props = init_1.properties.filter(function (key) { return key.name === pkg; });
                            if (!props.length) {
                                //insertImports.call(p, pkg);
                                var lowername = pkg.toLowerCase();
                                p.insertBefore(t.importDeclaration([t.importDefaultSpecifier(t.identifier(pkg))], t.stringLiteral("./packages/" + lowername + "/index.js")));
                                p.insertBefore(t.importDeclaration([], t.stringLiteral("./packages/" + lowername + "/" + lowername + ".scss")));
                                p.insertBefore(t.stringLiteral(emptyLine));
                                //addToExport.call(p, pkg, init);
                                init_1.properties.push(createProp(pkg));
                                p.replaceWith(t.variableDeclaration('const', [t.variableDeclarator(t.identifier(PKGS), init_1)]));
                                p.insertAfter(t.stringLiteral(emptyLine));
                                p.stop();
                                break;
                            }
                        }
                    }
                }
            }
        },
    };
    var code = transformCodes(codes, visitor);
    return code;
}
function createPkgDeclare(pkg) {
    var code = addPkgDeclare(pkg);
    fs.writeFileSync(nutMainFile, code.replace(/"\/\*hr\*\/"/g, ''));
    fs.appendFileSync(nutTypings, "export declare class " + pkg + " extends UIComponent {}\n");
}
function createNew() {
    if (newCpt.type == 'method')
        return new Promise(function (resolve, reject) {
            resolve();
        });
    var createIndexJs = new Promise(function (resolve, reject) {
        var nameLc = newCpt.name.toLowerCase();
        var content = "import " + newCpt.name + " from './" + nameLc + ".vue';\nimport './" + nameLc + ".scss';\n\n" + newCpt.name + ".install = function(Vue) {\n  Vue." + newCpt.type + "(" + newCpt.name + ".name, " + newCpt.name + ");\n};\n\nexport default " + newCpt.name;
        var content2 = newCpt.name + ".install = function(Vue) {\nVue." + newCpt.type + "(" + newCpt.name + ".name, " + newCpt.name + ");\n};\n\nexport default " + newCpt.name;
        var dirPath = path.join(dic_1.ROOT_PACKAGE_PATH('src/packages/' + nameLc));
        var filePath = path.join(dirPath, "index.js");
        if (!fs.existsSync(dirPath)) {
            fs.mkdirSync(dirPath);
        }
        if (newCpt.type == 'filter' || newCpt.type == 'directive') {
            content = content2;
        }
        fs.writeFile(filePath, content, function (err) {
            if (err)
                throw err;
            resolve("\u751F\u6210index.js\u6587\u4EF6\u6210\u529F");
        });
    });
    createIndexJs
        .then(function () {
        if (newCpt.type == 'component' || newCpt.type == 'method') {
            return createVue();
        }
        else {
            return;
        }
    })
        .then(function () {
        return createScss();
    })
        .then(function () {
        return createDemo();
    })
        .then(function () {
        return createDoc();
    })
        .then(function () {
        return createTest();
    })
        .then(function () {
        return addToPackageJson();
    })
        .then(function () {
        createPkgDeclare(newCpt.name);
        console.log('组件模板生成完毕，请开始你的表演~');
        process.exit();
    });
}
function createComponent() {
    return __awaiter(this, void 0, void 0, function () {
        return __generator(this, function (_a) {
            init();
            return [2 /*return*/];
        });
    });
}
exports.default = createComponent;
//# sourceMappingURL=createCptTpl.js.map