'use strict';

var tslib = require('tslib');
var core = require('@cromwell/core');
var coreBackend = require('@cromwell/core-backend');
var utils = require('@cromwell/utils');
var child_process = require('child_process');
var compress = require('compression');
var fastify = require('fastify');
var fs = require('fs-extra');
var path = require('path');
var symlinkDir = require('symlink-dir');
var middie = require('middie');
var fastifyStatic = require('fastify-static');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var compress__default = /*#__PURE__*/_interopDefaultLegacy(compress);
var fastify__default = /*#__PURE__*/_interopDefaultLegacy(fastify);
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
var symlinkDir__default = /*#__PURE__*/_interopDefaultLegacy(symlinkDir);
var middie__default = /*#__PURE__*/_interopDefaultLegacy(middie);
var fastifyStatic__default = /*#__PURE__*/_interopDefaultLegacy(fastifyStatic);

/*!
 * normalize-path <https://github.com/jonschlinkert/normalize-path>
 *
 * Copyright (c) 2014-2018, Jon Schlinkert.
 * Released under the MIT License.
 */

var normalizePath = function(path, stripTrailing) {
  if (typeof path !== 'string') {
    throw new TypeError('expected path to be a string');
  }

  if (path === '\\' || path === '/') return '/';

  var len = path.length;
  if (len <= 1) return path;

  // ensure that win32 namespaces has two leading slashes, so that the path is
  // handled properly by the win32 version of path.parse() after being normalized
  // https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces
  var prefix = '';
  if (len > 4 && path[3] === '\\') {
    var ch = path[2];
    if ((ch === '?' || ch === '.') && path.slice(0, 2) === '\\\\') {
      path = path.slice(2);
      prefix = '//';
    }
  }

  var segs = path.split(/[/\\]+/);
  if (stripTrailing !== false && segs[segs.length - 1] === '') {
    segs.pop();
  }
  return prefix + segs.join('/');
};

var start = function () { return tslib.__awaiter(void 0, void 0, void 0, function () {
    var watch, cmsConfig, env, isProduction, isDevelopment, projectPublicDir, publicDir, webTempDir, adminPanelStaticDir, serviceBuildDir, webTempServiceLink, bundledModulesDir, bundledLocalLink, port, app, bs, indexPageHandle, buildProc;
    var _a;
    return tslib.__generator(this, function (_b) {
        switch (_b.label) {
            case 0:
                watch = true;
                cmsConfig = coreBackend.readCMSConfigSync();
                core.setStoreItem('cmsSettings', cmsConfig);
                env = process.argv[2];
                isProduction = env === 'production' || env === 'prod';
                isDevelopment = env === 'development' || env === 'dev';
                if (!isDevelopment && !isProduction)
                    throw ("devServer::startDevServer: process.argv[2] is invalid - " + env + " valid values - \"development\" and \"production\"");
                return [4 /*yield*/, utils.downloader()];
            case 1:
                _b.sent();
                projectPublicDir = normalizePath(coreBackend.getPublicDir());
                publicDir = normalizePath(coreBackend.getAdminPanelWebPublicDir());
                webTempDir = normalizePath(coreBackend.getAdminPanelTempDir());
                adminPanelStaticDir = normalizePath(coreBackend.getAdminPanelStaticDir());
                if (!!fs__default['default'].existsSync(webTempDir)) return [3 /*break*/, 3];
                return [4 /*yield*/, fs__default['default'].ensureDir(webTempDir)];
            case 2:
                _b.sent();
                _b.label = 3;
            case 3:
                if (!(!fs__default['default'].existsSync(publicDir) && fs__default['default'].existsSync(projectPublicDir))) return [3 /*break*/, 5];
                return [4 /*yield*/, symlinkDir__default['default'](projectPublicDir, publicDir)];
            case 4:
                _b.sent();
                _b.label = 5;
            case 5:
                serviceBuildDir = coreBackend.getAdminPanelServiceBuildDir();
                webTempServiceLink = coreBackend.getAdminPanelWebServiceBuildDir();
                if (!(!fs__default['default'].existsSync(webTempServiceLink) && fs__default['default'].existsSync(serviceBuildDir))) return [3 /*break*/, 7];
                return [4 /*yield*/, symlinkDir__default['default'](serviceBuildDir, webTempServiceLink)];
            case 6:
                _b.sent();
                _b.label = 7;
            case 7:
                bundledModulesDir = utils.getBundledModulesDir();
                bundledLocalLink = path.resolve(webTempDir, utils.bundledModulesDirName);
                if (!(!fs__default['default'].existsSync(bundledLocalLink) && fs__default['default'].existsSync(bundledModulesDir))) return [3 /*break*/, 9];
                return [4 /*yield*/, symlinkDir__default['default'](bundledModulesDir, bundledLocalLink)];
            case 8:
                _b.sent();
                _b.label = 9;
            case 9:
                port = (_a = process.env.PORT) !== null && _a !== void 0 ? _a : cmsConfig.adminPanelPort;
                app = fastify__default['default']();
                return [4 /*yield*/, app.register(middie__default['default'])];
            case 10:
                _b.sent();
                if (isDevelopment) {
                    bs = require('browser-sync').create();
                    bs.init({ watch: false });
                    app.use(require('connect-browser-sync')(bs));
                }
                app.use(compress__default['default']());
                app.register(fastifyStatic__default['default'], {
                    root: publicDir,
                });
                app.register(fastifyStatic__default['default'], {
                    root: webTempDir + '/bundled-modules',
                    prefix: '/bundled-modules/',
                    decorateReply: false,
                });
                app.register(fastifyStatic__default['default'], {
                    root: adminPanelStaticDir,
                    prefix: '/admin/static/',
                    decorateReply: false,
                });
                app.register(fastifyStatic__default['default'], {
                    root: webTempDir + '/build',
                    prefix: '/admin/build/',
                    decorateReply: false,
                });
                indexPageHandle = function (req, res) {
                    // route requested, send index.html 
                    res.type('text/html').send("\n        <head>\n            <meta charset=\"UTF-8\">\n            <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n            <title>Cromwell CMS Admin Panel</title>\n            <script>\n            CromwellStore = {\n                cmsSettings: " + JSON.stringify(cmsConfig) + ",\n                environment: {\n                    isAdminPanel: true,\n                    mode: '" + (isDevelopment ? 'dev' : 'prod') + "'\n                }\n            }\n            </script>\n            <link href=\"https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;900&display=swap\" rel=\"stylesheet\">\n        </head>\n\n        <body>\n            <noscript>You need to enable JavaScript to run this app.</noscript>\n            <div id=\"root\"></div>\n            <script src=\"/admin/build/webapp.js\"></script>\n        </body>\n        ");
                };
                app.get("/admin", indexPageHandle);
                app.get("/admin/", indexPageHandle);
                app.get("/admin/#", indexPageHandle);
                app.get("/admin/#/", indexPageHandle);
                app.get("/admin/#/*", indexPageHandle);
                return [4 /*yield*/, app.listen(port, '::', 1, function (err) {
                        if (err) {
                            console.error(err);
                            if (process.send)
                                process.send(coreBackend.adminPanelMessages.onStartErrorMessage);
                        }
                        else {
                            console.log("Admin Panel server has started at " + core.serviceLocator.getAdminPanelUrl());
                            if (process.send)
                                process.send(coreBackend.adminPanelMessages.onStartMessage);
                        }
                    })];
            case 11:
                _b.sent();
                if (isDevelopment) {
                    buildProc = child_process.fork(path.resolve(serviceBuildDir, 'compiler.js'), watch ? ['--watch'] : [], { stdio: 'inherit', cwd: coreBackend.getAdminPanelDir(), env: { NODE_ENV: 'development' } });
                    buildProc.on('message', function (message) {
                        if (message === coreBackend.adminPanelMessages.onBuildEndMessage && bs) {
                            bs.reload();
                        }
                    });
                }
                return [2 /*return*/];
        }
    });
}); };
try {
    start();
}
catch (e) {
    console.error(e);
    if (process.send)
        process.send(coreBackend.adminPanelMessages.onStartErrorMessage);
}
