'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.setup = setup;
exports.render = render;

var _path = require('path');

var _ejs = require('ejs');

var _htmlescape = require('htmlescape');

var _htmlescape2 = _interopRequireDefault(_htmlescape);

var _color = require('color');

var _color2 = _interopRequireDefault(_color);

var _file = require('@uiengine/core/lib/util/file');

var _file2 = _interopRequireDefault(_file);

var _locales = require('./locales');

var _locales2 = _interopRequireDefault(_locales);

var _util = require('./util');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const supportedLocales = ['en', 'de'];
const defaultOpts = {
  lang: 'en',
  hljs: 'atom-one-dark',
  base: '/',
  cache: true,
  customStylesFile: null

  // templates are loaded on setup
};const templates = {};
const templatesPath = (0, _path.resolve)(__dirname, '..', 'lib', 'templates');
const staticPath = (0, _path.resolve)(__dirname, '..', 'dist');
const templatePath = template => (0, _path.join)(templatesPath, `${template}.ejs`);

// template helpers
const helpers = {
  htmlescape: _htmlescape2.default,
  dasherize: _util.dasherize,
  titleize: _util.titleize,

  color(value) {
    const color = (0, _color2.default)(value);

    return {
      hex: color.hex().toString(),
      rgb: color.rgb().toString(),
      hsl: color.hsl().toString().replace(/(\(\d+\.(\d{1,3}))\d+/, '$1') // shorten the first values decimal places
    };
  },

  localize(locale, key, interpolations) {
    const dict = _locales2.default[locale];

    return (0, _util.localize)(dict, key, interpolations);
  }
};

async function copyStatic(target) {
  await _file2.default.copy(staticPath, target);
}

async function compileTemplate(name) {
  const templateString = await _file2.default.read(templatePath(name));

  templates[name] = (0, _ejs.compile)(templateString);
}

async function setup(options) {
  // configure markdown renderer
  const { markdownIt, target } = options;
  markdownIt.set({ highlight: _util.highlight });

  // load and assign template
  try {
    await Promise.all([compileTemplate('index'), compileTemplate('sketch'), copyStatic(target)]);
  } catch (err) {
    const message = ['UI setup failed:', err];

    if (options.debug) message.push(JSON.stringify(options, null, 2));

    throw new Error(message.join('\n\n'));
  }
}

async function render(options, template = 'index', data = null) {
  // sanitize and prepare options
  if (!supportedLocales.includes(options.lang)) delete options.lang;
  const opts = Object.assign({}, defaultOpts, options);
  const basePath = opts.base.replace(/\/$/, '');
  const context = Object.assign({ basePath, helpers }, data, opts);

  try {
    if (!options.cache) await compileTemplate(template);

    const templateFn = templates[template];
    const rendered = templateFn(context);

    if (template === 'index') {
      const { target } = options;
      const filePath = (0, _path.resolve)(target, 'index.html');

      await _file2.default.write(filePath, rendered);
    }

    return rendered;
  } catch (err) {
    const message = [`UI could not render template "${template}":`, err];

    if (options.debug) message.push(JSON.stringify(context, null, 2));

    const error = new Error(message.join('\n\n'));
    error.code = err.code;
    error.path = templatePath(template);

    throw error;
  }
}