const EndOfLine = require('os').EOL;
const Render = require('json-templater/string');
const Fs = require('mz/fs');
const Common = require('../common');

// 路由模版
const ROUTER_TPL = `{
  path: '{{path}}',
  name: '{{name}}',
  component: resolve => {
    require.ensure([], () => {
      resolve(require('{{componentPath}}'))
    }, '{{componentPkg}}');
  }
}`;

// 父路由模版
const PARENT_ROUTER_TPL = `{
  path: '{{path}}',
  component: resolve => {
    require.ensure([], () => {
      resolve(require('{{componentPath}}'))
    }, '{{componentPkg}}');
  },
  children: [
{{childStr}}
  ]
}`;

// import语句模版
const IMPORT_EXTRA_ROUTER_TPL = 'import _{{fileName}} from \'./{{fileName}}\';';

// 手动路由添加模版
const CONCAT_EXTRA_TPL = 'routes = routes.concat(_{{fileName}});';

// 全部文件模版
const MAIN_TPL = `{{note}}
import Vue from 'vue';
import Router from 'vue-router';
Vue.use(Router);

let routes = [
{{routeListStr}}
];

{{extraImportStr}}
{{concatExtraStr}}

export default new Router({routes})
`;

module.exports = async ({extraRouterFileList, routerList, routerIndexPath}) => {
    if (!extraRouterFileList || !routerList || !routerIndexPath) {
        throw new TypeError('The extraRouterFileList,routerList,routerIndexPath should set');
    }

    // 生成手动配置代码
    const extraImportStr = extraRouterFileList
        .map(fileName => Render(IMPORT_EXTRA_ROUTER_TPL, {fileName}))
        .join(EndOfLine);
    const concatExtraStr = extraRouterFileList
        .map(fileName => Render(CONCAT_EXTRA_TPL, {fileName}))
        .join(EndOfLine);

    // 渲染自动生成路由
    const renderRouter = (routers) => {
        return routers.map(router => {
            if (router.children) {
                const childStr = renderRouter(router.children);
                delete router.children;
                router.childStr = childStr;
                return Render(PARENT_ROUTER_TPL, router);
            }
            return Render(ROUTER_TPL, router);
        }).join(',');
    };
    const routeListStr = renderRouter(routerList);

    // 渲染整个文件
    const context = Render(MAIN_TPL,
        {note: Common.NOTE, routeListStr, extraImportStr, concatExtraStr});

    // 写入文件
    await Fs.writeFile(routerIndexPath, context);
};
