'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getTemplatesAndPartials = getTemplatesAndPartials;
exports.addOrder = addOrder;
exports.getAbeImport = getAbeImport;
exports.includePartials = includePartials;
exports.translate = translate;
exports.getTemplate = getTemplate;
exports.getVariablesInWhere = getVariablesInWhere;
exports.recurseWhereVariables = recurseWhereVariables;
exports.getTemplatesTexts = getTemplatesTexts;
exports.execRequestColumns = execRequestColumns;
exports.getAbeRequestWhereKeysFromTemplates = getAbeRequestWhereKeysFromTemplates;
exports.setAbeSlugDefaultValueIfDoesntExist = setAbeSlugDefaultValueIfDoesntExist;
exports.getAbeSlugFromTemplates = getAbeSlugFromTemplates;
exports.setAbePrecontribDefaultValueIfDoesntExist = setAbePrecontribDefaultValueIfDoesntExist;
exports.getAbePrecontribFromTemplates = getAbePrecontribFromTemplates;
exports.getStructureAndTemplates = getStructureAndTemplates;

var _fsExtra = require('fs-extra');

var _fsExtra2 = _interopRequireDefault(_fsExtra);

var _bluebird = require('bluebird');

var _path = require('path');

var _path2 = _interopRequireDefault(_path);

var _ = require('../../');

var _sourceAttr = require('../../cms/editor/handlebars/sourceAttr');

var sourceAttr = _interopRequireWildcard(_sourceAttr);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

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

function getTemplatesAndPartials(templatesPath) {
  var p = new _bluebird.Promise(function (resolve) {
    var extension = '.' + _.config.files.templates.extension;
    return _.coreUtils.file.getFilesAsync(templatesPath, true, extension).then(function (files) {
      return resolve(files);
    });
  });

  return p;
}

function addOrder(text) {
  var regAbe = /{{abe[\S\s].*?key=['|"]([\S\s].*?['|"| ]}})/g;
  var matches = text.match(regAbe);
  var order = 0;

  if (typeof matches !== 'undefined' && matches !== null) {
    Array.prototype.forEach.call(matches, function (match) {
      if (typeof match !== 'undefined' && match !== null) {

        var orderAttr = _.cmsData.regex.getAttr(match, 'order');

        if (typeof orderAttr === 'undefined' || orderAttr === null || orderAttr === '') {
          var matchOrder = match.replace(/\}\}$/, ' order=\'' + order + '\'}}');
          text = text.replace(match, matchOrder);
        }
        order++;
      }
    });
  }
  return text;
}

function getAbeImport(text) {
  var partials = [];
  var listReg = /({{abe.*type=[\'|\"]import.*}})/g;
  var match;
  while (match = listReg.exec(text)) {
    partials.push(match[0]);
  }

  return partials;
}

function includePartials(text, json) {
  var abeImports = _.cmsTemplates.template.getAbeImport(text);

  Array.prototype.forEach.call(abeImports, function (abeImport) {
    var obj = _.cmsData.attributes.getAll(abeImport, {});

    var file = obj.file;
    var partial = '';
    file = _path2.default.join(_.config.root, _.config.partials, file);

    if (file.indexOf('{{') > -1) {
      var keys = sourceAttr.getKeys(file);
      Array.prototype.forEach.call(keys, function (key) {
        try {
          var toEval = '' + key.replace(/(\[|\.|\])/g, '\\$1');
          file = file.replace(new RegExp('{{' + toEval + '}}', 'g'), eval('json.' + key));
        } catch (e) {}
      });
    }

    if (_.coreUtils.file.exist(file)) {
      partial = _.cmsTemplates.template.includePartials(_fsExtra2.default.readFileSync(file, 'utf8'), json);
    }
    text = text.replace(_.cmsData.regex.escapeTextToRegex(abeImport, 'g'), partial);
  });

  return text;
}

function translate(text) {
  var importReg = /({{abe.*type=[\'|\"]translate.*}})/g;

  var matches = text.match(importReg);

  if (typeof matches !== 'undefined' && matches !== null) {
    Array.prototype.forEach.call(matches, function (match) {
      var splitedMatches = match.split('{{abe ');

      Array.prototype.forEach.call(splitedMatches, function (splitedMatch) {
        var currentMatch = '{{abe ' + splitedMatch;
        if (/({{abe.*type=[\'|\"]translate.*}})/.test(currentMatch)) {
          var locale = _.cmsData.regex.getAttr(currentMatch, 'locale');
          var source = _.cmsData.regex.getAttr(currentMatch, 'source');

          if (locale.indexOf('{{') === -1) {
            locale = '\'' + locale + '\'';
          } else {
            locale = locale.replace(/\{\{(.*?)\}\}/, '$1');
          }

          if (source.indexOf('{{') === -1) {
            source = '\'' + source.replace(/'/g, '\\\'') + '\'';
          } else {
            source = source.replace(/\{\{(.*?)\}\}/, '$1');
          }

          // var replace = `{{{i18nAbe ${locale} ${source}}}}`
          var replace = currentMatch.replace('{{abe', '{{i18nAbe');
          replace = replace.replace(/locale=['|"].*?['|"]/, locale);
          replace = replace.replace(/source=['|"].*?['|"]/, source);
          replace = replace.replace(/{{i18nAbe.*?}}/, '{{{i18nAbe ' + locale + ' ' + source + '}}}');

          text = text.replace(_.cmsData.regex.escapeTextToRegex(currentMatch, 'g'), replace);
        }
      });
    });
  }

  return text;
}

function getTemplate(file) {
  var json = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

  var text = '';

  // HOOKS beforeGetTemplate
  file = _.abeExtend.hooks.instance.trigger('beforeGetTemplate', file);

  file = file.replace(_path2.default.join(_.config.root, _.config.templates.url), '');
  file = file.replace(_.config.root, '');
  if (file.indexOf('.') > -1) {
    file = file.replace(/\..+$/, '');
  }
  file = _path2.default.join(_.config.root, _.config.templates.url, file + '.' + _.config.files.templates.extension);
  if (_.coreUtils.file.exist(file)) {
    text = _fsExtra2.default.readFileSync(file, 'utf8');
    text = _.cmsTemplates.template.includePartials(text, json);
    text = _.cmsTemplates.template.translate(text);
    text = _.cmsTemplates.template.addOrder(text);
  } else {
    text = '[ ERROR ] template ' + (file + '.' + _.config.files.templates.extension) + ' doesn\'t exist anymore';
  }

  // HOOKS afterGetTemplate
  text = _.abeExtend.hooks.instance.trigger('afterGetTemplate', text);

  return text;
}

function getVariablesInWhere(where) {
  var ar = [];

  if (where.left.column.indexOf('{{') > -1) {
    ar.push(where.left.column.replace(/\{\{(.*?)\}\}/, '$1'));
  } else {
    ar.push(where.left.column);
  }

  if (where.right.value) {
    if (typeof where.right.value === 'string') {
      if (where.right.value && where.right.value.indexOf('{{') > -1) {
        ar.push(where.right.value.replace(/\{\{(.*?)\}\}/, '$1'));
      }
    } else {
      where.right.value.forEach(function (value) {
        if (value.column.indexOf('{{') > -1) {
          ar.push(value.column.replace(/\{\{(.*?)\}\}/, '$1'));
        }
      });
    }
  }

  if (where.right.column && where.right.column.indexOf('{{') > -1) {
    ar.push(where.right.column.replace(/\{\{(.*?)\}\}/, '$1'));
  }

  return ar;
}

/**
 * Get columns and where.left ids of a select statement
 *
 * select title, image from ../ where template=""
 *
 * return [title, image, template]
 * 
 * @param  {Array} templatesList ["article.html", "other.html"]
 * @return {Promise}
 */
function recurseWhereVariables(where) {
  var ar = [];
  var arLeft;
  var arRight;
  switch (where.operator) {
    case 'AND':
      arLeft = _.cmsTemplates.template.recurseWhereVariables(where.left);
      arRight = _.cmsTemplates.template.recurseWhereVariables(where.right);
      return arLeft.concat(arRight);
      break;
    case 'OR':
      arLeft = _.cmsTemplates.template.recurseWhereVariables(where.left);
      arRight = _.cmsTemplates.template.recurseWhereVariables(where.right);
      return arLeft.concat(arRight);
      break;
    default:
      ar = getVariablesInWhere(where);
      break;
  }

  return ar;
}

function getTemplatesTexts(templatesList, json) {
  var templates = [];
  var p = new _bluebird.Promise(function (resolve) {
    Array.prototype.forEach.call(templatesList, function (file) {
      var template = _fsExtra2.default.readFileSync(file, 'utf8');
      template = _.cmsTemplates.template.includePartials(template, json);
      var name = file.replace(_path2.default.join(_.config.root, _.config.templates.url, _path2.default.sep), '').replace('.' + _.config.files.templates.extension, '');
      templates.push({
        name: name,
        path: file,
        template: template
      });
    });
    resolve(templates);
  });

  return p;
}

function execRequestColumns(tpl) {
  var ar = [];
  var matches = _.cmsData.regex.getTagAbeTypeRequest(tpl);
  Array.prototype.forEach.call(matches, function (match) {
    var obj = _.cmsData.attributes.getAll(match[0], {});
    var type = _.cmsData.sql.getSourceType(obj.sourceString);
    switch (type) {
      case 'request':
        var request = _.cmsData.sql.handleSqlRequest(obj.sourceString, {});
        if (typeof request.columns !== 'undefined' && request.columns !== null) {
          Array.prototype.forEach.call(request.columns, function (column) {
            ar.push(column);
          });
        }
        if (typeof request.where !== 'undefined' && request.where !== null) {
          ar = ar.concat(_.cmsTemplates.template.recurseWhereVariables(request.where));
        }
    }
  });

  return ar;
}

function getAbeRequestWhereKeysFromTemplates(templatesList) {
  var whereKeys = [];
  var p = new _bluebird.Promise(function (resolve) {
    Array.prototype.forEach.call(templatesList, function (file) {
      whereKeys = whereKeys.concat(_.cmsTemplates.template.execRequestColumns(file.template));
    });
    whereKeys = whereKeys.filter(function (item, pos) {
      return whereKeys.indexOf(item) == pos;
    });
    resolve(whereKeys);
  });

  return p;
}

function setAbeSlugDefaultValueIfDoesntExist(templateText) {
  var matches = _.cmsData.regex.getTagAbeWithType(templateText, 'slug');
  if (matches == null || matches[0] == null) {
    templateText = '{{abe type="slug" source="{{name}}"}}\n' + templateText;
  }

  return templateText;
}

function getAbeSlugFromTemplates(templatesList) {
  var slugs = {};
  Array.prototype.forEach.call(templatesList, function (file) {
    var templateText = _.cmsTemplates.template.setAbeSlugDefaultValueIfDoesntExist(file.template);
    var matchesSlug = _.cmsData.regex.getTagAbeWithType(templateText, 'slug');
    var obj = _.cmsData.attributes.getAll(matchesSlug[0], {});
    slugs[file.name] = obj.sourceString;
  });
  return slugs;
}

function setAbePrecontribDefaultValueIfDoesntExist(templateText) {
  var matches = _.cmsData.regex.getTagAbeWithTab(templateText, 'slug');
  if (matches == null || matches[0] == null) {
    templateText = '{{abe type=\'text\' key=\'name\' desc=\'Name\' required="true" tab="slug" visible="false"}}\n' + templateText;
  }

  return templateText;
}

function getAbePrecontribFromTemplates(templatesList) {
  var fields = [];
  var precontributionTemplate = '';
  Array.prototype.forEach.call(templatesList, function (file) {
    var slugMatch = _.cmsData.regex.getTagAbeWithType(file.template, 'slug');
    var templateText = file.template;
    if (slugMatch == null || slugMatch[0] == null) {
      templateText = _.cmsTemplates.template.setAbePrecontribDefaultValueIfDoesntExist(file.template);
    }

    var matchesTabSlug = _.cmsData.regex.getTagAbeWithTab(templateText, 'slug');
    Array.prototype.forEach.call(matchesTabSlug, function (match) {
      fields.push(_.cmsData.attributes.getAll(match, {}));
      var tag = match.replace(/\}\}$/, ' precontribTemplate="' + file.name + '"}}');
      tag = tag.replace(/(key=[\'|\"])(.*?)([\'|\"])/, '$1/' + file.name + '/$2$3');
      precontributionTemplate += tag + '\n';
    });
  });

  precontributionTemplate = _.cmsTemplates.template.addOrder(precontributionTemplate);

  return {
    fields: fields,
    template: precontributionTemplate
  };
}

function getStructureAndTemplates() {
  var pathStructure = _path2.default.join(_.config.root, _.config.structure.url);
  var pathTemplates = _path2.default.join(_.config.root, _.config.templates.url);
  var extension = '.' + _.config.files.templates.extension;
  var result = { 'structure': [], 'templates': [] };

  result.structure = _.coreUtils.file.getFoldersSync(pathStructure, true);
  var templatePaths = _.coreUtils.file.getFilesSync(pathTemplates, true, extension);
  Array.prototype.forEach.call(templatePaths, function (templatePath) {
    var additionalPath = _path2.default.dirname(templatePath).replace(pathTemplates, '');
    if (additionalPath !== '') additionalPath = additionalPath.substring(1);
    var name = _path2.default.join(additionalPath, _path2.default.basename(templatePath, extension));
    var template = { 'path': templatePath, 'name': name };
    result.templates.push(template);
  });

  return result;
}