"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 __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
    result["default"] = mod;
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const Mustache = __importStar(require("mustache"));
const FS = __importStar(require("fs"));
const Path = __importStar(require("path"));
const Walk = __importStar(require("walk"));
const Utils = __importStar(require("../../util/src"));
const Type = __importStar(require("./type"));
const CopyDIR = require('copy-dir');
class ACProject {
    constructor(path) {
        if (path) {
            this.pkg = JSON.parse(FS.readFileSync(Path.join(path, 'package.json')).toString());
        }
    }
    create(option) {
        return __awaiter(this, void 0, void 0, function* () {
            switch (option.type) {
                case Type.ProjectType.Application:
                    return yield this.createApplicationProject(option);
                case Type.ProjectType.Falcons:
                    return yield this.createTemplatesProject(option);
                default:
                    return Promise.reject(new Error(`无效的工程参数 \n${JSON.stringify(option, undefined, 2)}`));
            }
        });
    }
    createTemplatesProject(option) {
        return __awaiter(this, void 0, void 0, function* () {
            if (FS.existsSync(option.path)) {
                return Promise.reject(new Error(`工程已存在 ${option.path}`));
            }
            FS.mkdirSync(option.path);
            const mode = this.project(option.id);
            if (!mode) {
                return Promise.reject(new Error(`无效的工程模式 ${option.id} : ${option.type}`));
            }
            const fillup = (modepath, optionpath, filename, value) => {
                let content = FS.readFileSync(Path.join(modepath, filename)).toString();
                content = Mustache.render(content, value);
                FS.writeFileSync(Path.join(optionpath, filename), content);
            };
            //  fill package
            fillup(mode.path, option.path, 'package.json', option);
            if (option.templates) {
                for (let index = 0; index < option.templates.length; index++) {
                    const tploption = option.templates[index];
                    tploption.path = Path.join(option.path, `${tploption.name}`);
                    yield this.createTemplateFiles(tploption);
                }
            }
            return Promise.resolve();
        });
    }
    createTemplateFiles(option) {
        return __awaiter(this, void 0, void 0, function* () {
            if (FS.existsSync(option.path)) {
                return Promise.reject(`模版已存在 ${option.path}`);
            }
            FS.mkdirSync(option.path);
            const mode = this.template(option.id);
            if (!mode) {
                return Promise.reject(new Error(`无效的模版类型 ${option.id} : ${option.name}`));
            }
            const fillup = (modepath, optionpath, filename, value) => {
                let content = FS.readFileSync(Path.join(modepath, filename)).toString();
                content = Mustache.render(content, value);
                FS.writeFileSync(Path.join(optionpath, filename), content);
            };
            fillup(mode.path, option.path, 'main.vue', option);
            fillup(mode.path, option.path, 'manifest.json', option);
            fillup(mode.path, option.path, 'mock.json', option);
            return Promise.resolve();
        });
    }
    createApplicationProject(option) {
        return __awaiter(this, void 0, void 0, function* () {
            if (FS.existsSync(option.path)) {
                return Promise.reject(new Error(`工程已存在 ${option.path}`));
            }
            return new Promise((resolve, rejects) => {
                const mode = this.project(option.id);
                if (mode) {
                    CopyDIR(mode.path, option.path, (stats, filepath, filename) => {
                        return ['info.json'].indexOf(filename) === -1 ? true : false;
                    }, (err) => {
                        if (err) {
                            rejects(err);
                        }
                        else {
                            Walk.walkSync(option.path, {
                                listeners: {
                                    file: (root, names, next) => {
                                        option.type = mode.type;
                                        const fpath = Path.join(root, names.name);
                                        let content = FS.readFileSync(fpath).toString();
                                        content = Mustache.render(content, option);
                                        FS.writeFileSync(fpath, content);
                                        next();
                                    },
                                    errors: (root, names, next) => {
                                        next();
                                    }
                                }
                            });
                            resolve();
                        }
                    });
                }
                else {
                    rejects(new Error('invalid project type'));
                }
            });
        });
    }
    projects() {
        const modes = new Array();
        this.index().projects.forEach((ele) => {
            modes.push(new ACMode(ele));
        });
        return modes;
    }
    project(id) {
        return this.projects().filter(value => {
            return value.id === id;
        })[0];
    }
    templates() {
        const modes = new Array();
        this.index().templates.forEach((ele) => {
            modes.push(new ACMode(ele));
        });
        return modes;
    }
    template(id) {
        return this.templates().filter(value => {
            return value.id === id;
        })[0];
    }
    sdks() {
        return this.index().cubeSDK;
    }
    index() {
        return JSON.parse(FS.readFileSync(Path.join(Utils.ACUtils.respath, `template/index.json`)).toString());
    }
}
exports.ACProject = ACProject;
class ACMode {
    constructor(id) {
        this.id = '';
        this.info = {};
        this.path = '';
        this.id = id;
        this.path = Path.join(Utils.ACUtils.respath, `template/${this.id}`);
        this.info = JSON.parse(FS.readFileSync(Path.join(this.path, `info.json`)).toString());
    }
    get name() {
        return this.info.name;
    }
    get type() {
        return this.info.type;
    }
}
exports.ACMode = ACMode;
//# sourceMappingURL=project.js.map