// Generated by CoffeeScript 2.3.2
(function() {
  // This module is meant to provide the basic building blocks
  // for a ES search request. The signature of each function should follow
  // the pattern (searchRequest, settings, attributes/sorter/suggestions)

  // The first argument, `searchRequest` describes the actual request.
  // It should be an object which at least two properties:

  //   - `query` is an object representing the url parameters of the original request

  //   - `type` is a string, the name of a type described in the configuration.

  // The second argument, `settings` contains the complete runtime configuration
  // of this irma instance. It is used to lookup types and attributes and stuff.

  // The remaining argument(s) are optional. If ommited, the values are derived from the
  // first two arguments. The idea is to allow custom reqeust transformers full control
  // over what attributes/sorters/suggesters are processed when and where and how.

  var semantics;

  module.exports.highlightFields = function(searchRequest, settings, attributes0) {
    var attr, attributes, hlFields, hlSettings, hlSubfields, i, len, ref, ref1, ref2, subfield;
    attributes = (ref = attributes0 != null ? attributes0 : settings != null ? (ref1 = settings.types) != null ? (ref2 = ref1[searchRequest.type]) != null ? ref2.attributes : void 0 : void 0 : void 0) != null ? ref : [];
    hlFields = {};
    for (i = 0, len = attributes.length; i < len; i++) {
      attr = attributes[i];
      if (attr.highlight != null) {
        hlFields[attr.field] = attr.highlight();
      }
      if (attr.highlightSubfields != null) {
        hlSubfields = attr.highlightSubfields();
        for (subfield in hlSubfields) {
          hlSettings = hlSubfields[subfield];
          hlFields[attr.field + "." + subfield] = hlSettings;
        }
      }
    }
    return hlFields;
  };

  module.exports.suggest = function(request, settings, suggestions0) {
    var i, len, query, ref, ref1, ref2, result, s, suggestion, suggestions, type;
    ({query, type} = request);
    suggestions = (ref = suggestions0 != null ? suggestions0 : settings != null ? (ref1 = settings.types) != null ? (ref2 = ref1[type]) != null ? ref2.suggestions : void 0 : void 0 : void 0) != null ? ref : [];
    result = {};
    for (i = 0, len = suggestions.length; i < len; i++) {
      suggestion = suggestions[i];
      s = suggestion.build(query, request, settings);
      if (s != null) {
        result[suggestion.name] = s;
      }
    }
    return result;
  };

  module.exports.sort = function({
      query: {sort} = {},
      type
    }, settings, SortParser0) {
    var SortParser, parse, ref, ref1, ref2, ref3, sorter;
    SortParser = (ref = SortParser0 != null ? SortParser0 : settings.SortParser) != null ? ref : require("./sort-parser");
    parse = SortParser((ref1 = (ref2 = settings.types) != null ? (ref3 = ref2[type]) != null ? ref3.sort : void 0 : void 0) != null ? ref1 : {});
    sorter = parse(sort);
    return sorter.sort();
  };

  module.exports.aggregations = function(searchRequest, settings, attributes0, SortParser0) {
    var SortParser, aggs, attr, attributes, i, len, parse, ref, ref1, ref2, ref3, ref4, ref5, sort, sorter, type;
    ({
      type = settings.defaultType,
      query: {sort} = {}
    } = searchRequest);
    SortParser = (ref = SortParser0 != null ? SortParser0 : settings.SortParser) != null ? ref : require("./sort-parser");
    attributes = attributes0 != null ? attributes0 : (ref1 = (ref2 = settings.types[type]) != null ? ref2.attributes : void 0) != null ? ref1 : [];
    aggs = {};
    for (i = 0, len = attributes.length; i < len; i++) {
      attr = attributes[i];
      if (attr.aggregation != null) {
        aggs[attr.name] = attr.aggregation(searchRequest, settings, attributes, SortParser);
      }
    }
    parse = SortParser((ref3 = (ref4 = settings.types) != null ? (ref5 = ref4[type]) != null ? ref5.sort : void 0 : void 0) != null ? ref3 : {});
    sorter = parse(sort);
    if ((sorter != null ? sorter.aggregation : void 0) != null) {
      aggs["_offsets"] = sorter.aggregation(searchRequest, settings, attributes, SortParser);
    }
    return aggs;
  };

  module.exports.explain = function({
      query: {explain} = {}
    }) {
    return 'true' === explain;
  };

  module.exports.type = function({type}, {defaultType}) {
    return type != null ? type : defaultType;
  };

  semantics = function(searchRequest, settings, semantics0) {
    var ref, ref1, searchSemantics, type;
    type = settings != null ? settings.types[searchRequest.type] : void 0;
    return searchSemantics = (ref = semantics0 != null ? semantics0 : settings != null ? (ref1 = settings.types[searchRequest.type]) != null ? ref1.searchSemantics : void 0 : void 0) != null ? ref : settings.searchSemantics;
  };

  module.exports.fielddataFields = function(searchRequest, settings, attributes, semantics0) {
    var searchSemantics;
    searchSemantics = semantics(searchRequest, settings, semantics0);
    if (module.exports.explain(searchRequest)) {
      return searchSemantics.apply(searchRequest, settings, attributes).fields;
    }
  };

  module.exports.query = function(searchRequest, settings, attributes, semantics0) {
    var searchSemantics;
    searchSemantics = semantics(searchRequest, settings, semantics0);
    return searchSemantics.apply(searchRequest, settings, attributes);
  };

  module.exports.size = function({
      query: {limit} = {}
    } = {}, {defaultLimit = 20, hardLimit = 250}) {
    return Math.min(limit != null ? limit : defaultLimit, hardLimit);
  };

  module.exports.from = function({
      query: {offset = 0} = {}
    } = {}) {
    return offset;
  };

}).call(this);
