// Generated by CoffeeScript 1.12.7
var geonamesCountryCodes;

geonamesCountryCodes = ["af", "eg", "ax", "al", "dz", "as", "vi", "ad", "ao", "ai", "aq", "ag", "gq", "ar", "am", "aw", "az", "et", "au", "bs", "bh", "bd", "bb", "be", "bz", "bj", "bm", "bt", "bo", "bq", "ba", "bw", "bv", "br", "vg", "io", "bn", "bg", "bf", "bi", "cl", "ck", "cr", "cw", "dk", "de", "dm", "do", "dj", "ec", "sv", "ci", "er", "ee", "fk", "fo", "fj", "fi", "fr", "gf", "pf", "tf", "ga", "gm", "ge", "gh", "gi", "gd", "gr", "gl", "gp", "gu", "gt", "gg", "gn", "gw", "gy", "ht", "hm", "hn", "hk", "in", "id", "im", "iq", "ir", "ie", "is", "il", "it", "jm", "jp", "ye", "je", "jo", "ky", "kh", "cm", "ca", "cv", "kz", "qa", "ke", "kg", "ki", "cc", "co", "km", "cd", "cg", "kp", "kr", "hr", "cu", "kw", "la", "ls", "lv", "lb", "lr", "ly", "li", "lt", "lu", "mo", "mg", "mw", "my", "mv", "ml", "mt", "ma", "mh", "mq", "mr", "mu", "yt", "mx", "fm", "md", "mc", "mn", "me", "ms", "mz", "mm", "na", "nr", "np", "nc", "nz", "ni", "nl", "ne", "ng", "nu", "mp", "mk", "nf", "no", "om", "at", "tl", "pk", "ps", "pw", "pa", "pg", "py", "pe", "ph", "pn", "pl", "pt", "pr", "tw", "re", "rw", "ro", "ru", "bl", "mf", "pm", "sb", "zm", "ws", "sm", "st", "sa", "se", "ch", "sn", "rs", "sc", "sl", "zw", "sg", "sx", "sk", "si", "so", "es", "sj", "lk", "sh", "kn", "lc", "vc", "za", "sd", "gs", "ss", "sr", "sz", "sy", "tj", "tz", "th", "tg", "tk", "to", "tt", "td", "cz", "tn", "tr", "tm", "tc", "tv", "ug", "ua", "hu", "um", "uy", "uz", "vu", "va", "ve", "ae", "us", "gb", "vn", "cn", "wf", "cx", "by", "eh", "cf", "cy"];
// Generated by CoffeeScript 1.12.7
ez5.GeonamesUtil = (function() {
  function GeonamesUtil() {}

  GeonamesUtil.getConceptNameFromObject = function(object) {
    var conceptName;
    conceptName = '';
    if (object != null ? object.asciiName : void 0) {
      conceptName = object.asciiName;
    }
    return conceptName;
  };

  GeonamesUtil.getConceptURIFromObject = function(object) {
    var conceptURI;
    conceptURI = '';
    if (object != null ? object.geonameId : void 0) {
      conceptURI = 'http://geonames.org/' + object.geonameId;
    }
    return conceptURI;
  };

  GeonamesUtil.getConceptAncestorsFromObject = function(object) {
    var conceptAncestors;
    conceptAncestors = [];
    if (object != null ? object.countryId : void 0) {
      conceptAncestors.push('http://geonames.org/' + object.countryId);
    }
    if (object != null ? object.adminId1 : void 0) {
      conceptAncestors.push('http://geonames.org/' + object.adminId1);
    }
    if (object != null ? object.adminId2 : void 0) {
      conceptAncestors.push('http://geonames.org/' + object.adminId2);
    }
    if (object != null ? object.adminId3 : void 0) {
      conceptAncestors.push('http://geonames.org/' + object.adminId3);
    }
    if (object != null ? object.adminId4 : void 0) {
      conceptAncestors.push('http://geonames.org/' + object.adminId4);
    }
    conceptAncestors.push('http://geonames.org/' + object.geonameId);
    conceptAncestors = conceptAncestors.join(' ');
    return conceptAncestors;
  };

  GeonamesUtil.getStandardTextFromObject = function(context, object, cdata, databaseLanguages) {
    var _standard, activeFrontendLanguage, i, l10nObject, l10nObjectKey, l10nObjectValue, language, len, ref, shortenedDatabaseLanguages, standardTextString;
    if (databaseLanguages == null) {
      databaseLanguages = false;
    }
    if (databaseLanguages === false) {
      databaseLanguages = ez5.loca.getDatabaseLanguages();
    }
    shortenedDatabaseLanguages = databaseLanguages.map(function(value, key, array) {
      return value.split('-').shift();
    });
    activeFrontendLanguage = null;
    if (context) {
      activeFrontendLanguage = context.getFrontendLanguage();
    }
    if (cdata != null ? cdata.frontendLanguage : void 0) {
      if ((cdata != null ? (ref = cdata.frontendLanguage) != null ? ref.length : void 0 : void 0) === 2) {
        activeFrontendLanguage = cdata.frontendLanguage;
      }
    }
    if (Array.isArray(object)) {
      object = object[0];
    }
    _standard = {};
    standardTextString = '';
    l10nObject = {};
    for (i = 0, len = databaseLanguages.length; i < len; i++) {
      language = databaseLanguages[i];
      l10nObject[language] = '';
    }
    for (l10nObjectKey in l10nObject) {
      l10nObjectValue = l10nObject[l10nObjectKey];
      l10nObject[l10nObjectKey] = object.asciiName;
    }
    _standard.l10ntext = l10nObject;
    return _standard;
  };

  GeonamesUtil.getFullTextFromObject = function(object, databaseLanguages) {
    var _fulltext, altnameVal, altnamekey, arrayValue, arrayValueOfObject, fullTextString, i, j, k, key, l, l10nObject, l10nObjectKey, l10nObjectValue, l10nObjectWithShortenedLanguages, l10nObjectWithShortenedLanguagesKey, l10nObjectWithShortenedLanguagesValue, language, len, len1, len2, len3, objectKey, objectKeys, objectValue, propertyType, ref, ref1, ref2, shortenedDatabaseLanguages, shortenedLanguage, value;
    if (databaseLanguages == null) {
      databaseLanguages = false;
    }
    if (databaseLanguages === false) {
      databaseLanguages = ez5.loca.getDatabaseLanguages();
    }
    shortenedDatabaseLanguages = databaseLanguages.map(function(value, key, array) {
      return value.split('-').shift();
    });
    if (Array.isArray(object)) {
      object = object[0];
    }
    _fulltext = {};
    fullTextString = '';
    l10nObject = {};
    l10nObjectWithShortenedLanguages = {};
    for (i = 0, len = databaseLanguages.length; i < len; i++) {
      language = databaseLanguages[i];
      l10nObject[language] = '';
    }
    for (j = 0, len1 = shortenedDatabaseLanguages.length; j < len1; j++) {
      language = shortenedDatabaseLanguages[j];
      l10nObjectWithShortenedLanguages[language] = '';
    }
    objectKeys = ["asciiName", "alternateNames", "toponymName", "geonameId", "countryName"];
    for (key in object) {
      value = object[key];
      if (objectKeys.includes(key)) {
        propertyType = typeof value;
        if (propertyType === 'string' || propertyType === 'number') {
          fullTextString += value + ' ';
          for (l10nObjectWithShortenedLanguagesKey in l10nObjectWithShortenedLanguages) {
            l10nObjectWithShortenedLanguagesValue = l10nObjectWithShortenedLanguages[l10nObjectWithShortenedLanguagesKey];
            l10nObjectWithShortenedLanguages[l10nObjectWithShortenedLanguagesKey] = l10nObjectWithShortenedLanguagesValue + value + ' ';
          }
        }
        if (propertyType === 'object') {
          if (Array.isArray(object[key])) {
            if (Array.isArray(object[key])) {
              ref = object[key];
              for (k = 0, len2 = ref.length; k < len2; k++) {
                arrayValue = ref[k];
                if (typeof arrayValue === 'string') {
                  fullTextString += arrayValue + ' ';
                  for (l10nObjectWithShortenedLanguagesKey in l10nObjectWithShortenedLanguages) {
                    l10nObjectWithShortenedLanguagesValue = l10nObjectWithShortenedLanguages[l10nObjectWithShortenedLanguagesKey];
                    l10nObjectWithShortenedLanguages[l10nObjectWithShortenedLanguagesKey] = l10nObjectWithShortenedLanguagesValue + arrayValue + ' ';
                  }
                }
              }
            }
            if (typeof object[key] === 'object') {
              ref1 = object[key];
              for (altnamekey in ref1) {
                altnameVal = ref1[altnamekey];
                if (altnameVal.name) {
                  fullTextString += altnameVal.name + ' ';
                  for (l10nObjectWithShortenedLanguagesKey in l10nObjectWithShortenedLanguages) {
                    l10nObjectWithShortenedLanguagesValue = l10nObjectWithShortenedLanguages[l10nObjectWithShortenedLanguagesKey];
                    l10nObjectWithShortenedLanguages[l10nObjectWithShortenedLanguagesKey] = l10nObjectWithShortenedLanguagesValue + altnameVal.name + ' ';
                  }
                }
              }
            }
          } else {
            ref2 = object[key];
            for (objectKey in ref2) {
              objectValue = ref2[objectKey];
              if (Array.isArray(objectValue)) {
                for (l = 0, len3 = objectValue.length; l < len3; l++) {
                  arrayValueOfObject = objectValue[l];
                  fullTextString += arrayValueOfObject + ' ';
                  if (l10nObjectWithShortenedLanguages.hasOwnProperty(objectKey)) {
                    l10nObjectWithShortenedLanguages[objectKey] += arrayValueOfObject + ' ';
                  }
                }
              }
              if (typeof objectValue === 'string') {
                fullTextString += objectValue + ' ';
                if (l10nObjectWithShortenedLanguages.hasOwnProperty(objectKey)) {
                  l10nObjectWithShortenedLanguages[objectKey] += objectValue + ' ';
                }
              }
            }
          }
        }
      }
    }
    for (l10nObjectKey in l10nObject) {
      l10nObjectValue = l10nObject[l10nObjectKey];
      shortenedLanguage = l10nObjectKey.split('-')[0];
      if (l10nObjectWithShortenedLanguages[shortenedLanguage]) {
        l10nObject[l10nObjectKey] = l10nObjectWithShortenedLanguages[shortenedLanguage];
      }
    }
    _fulltext.text = fullTextString;
    _fulltext.l10ntext = l10nObject;
    return _fulltext;
  };

  return GeonamesUtil;

})();
// Generated by CoffeeScript 1.12.7
var geonamesUpdate;

geonamesUpdate = (function() {
  function geonamesUpdate() {}

  geonamesUpdate.prototype.__start_update = function(arg) {
    var availabilityCheck_xhr, geonames_username, plugin_config, server_config, testURL;
    server_config = arg.server_config, plugin_config = arg.plugin_config;
    geonames_username = false;
    if (server_config.base.system.update_interval_geonames.geonames_username !== '') {
      geonames_username = server_config.base.system.update_interval_geonames.geonames_username;
    }
    if (geonames_username) {
      testURL = 'https://ws.gbv.de/suggest/geonames2/?searchterm=G%C3%B6ttingen&featureclass=P&country=DE&count=50&ancestors=true&language=de&expand=false';
      availabilityCheck_xhr = new CUI.XHR({
        url: testURL
      });
      return availabilityCheck_xhr.start().done(function(data, status, statusText) {
        var dataStr;
        dataStr = JSON.stringify(data);
        if (dataStr.includes('Göttingen')) {
          return ez5.respondSuccess({
            state: {
              "start_update": new Date().toUTCString(),
              "databaseLanguages": server_config.base.system.languages.database,
              "geonames_username": geonames_username,
              "default_language": server_config.base.system.update_interval_geonames.default_language
            }
          });
        } else {
          return ez5.respondError("custom.data.type.geonames.update.error.generic", {
            error: "Test on geonames-API was not successfull!"
          });
        }
      });
    } else {
      return ez5.respondError("custom.data.type.geonames.update.error.generic", {
        error: "No geonames-username for API given!"
      });
    }
  };

  geonamesUpdate.prototype.__updateData = function(arg) {
    var chunkWorkPromise, databaseLanguages, defaultLanguage, default_language, geonamesURI, geonamesURIs, geonames_username, j, len, object, objects, objectsMap, objectsToUpdate, plugin_config, ref, state, that, timeout;
    objects = arg.objects, plugin_config = arg.plugin_config, state = arg.state;
    that = this;
    objectsMap = {};
    geonamesURIs = [];
    databaseLanguages = state.databaseLanguages;
    default_language = state.default_language;
    geonames_username = state.geonames_username;
    defaultLanguage = false;
    if (default_language) {
      if (typeof default_language === 'string' || default_language instanceof String) {
        if (default_language.length === 2) {
          defaultLanguage = default_language;
        }
      }
    }
    for (j = 0, len = objects.length; j < len; j++) {
      object = objects[j];
      if (!(object.identifier && object.data)) {
        continue;
      }
      geonamesURI = object.data.conceptURI;
      if (CUI.util.isEmpty(geonamesURI)) {
        continue;
      }
      if (!objectsMap[geonamesURI]) {
        objectsMap[geonamesURI] = [];
      }
      objectsMap[geonamesURI].push(object);
      geonamesURIs.push(geonamesURI);
    }
    if (geonamesURIs.length === 0) {
      return ez5.respondSuccess({
        payload: []
      });
    }
    timeout = ((ref = plugin_config.update) != null ? ref.timeout : void 0) || 0;
    timeout *= 1000;
    geonamesURIs = geonamesURIs.filter((function(_this) {
      return function(x, i, a) {
        return a.indexOf(x) === i;
      };
    })(this));
    objectsToUpdate = [];
    chunkWorkPromise = CUI.chunkWork.call(this, {
      items: geonamesURIs,
      chunk_size: 1,
      call: (function(_this) {
        return function(items) {
          var callUrl, deferred, encodedURL, extendedInfo_xhr, geonamesID, originalUri, uri;
          uri = items[0];
          originalUri = items[0];
          geonamesID = uri.replace('http://www.geonames.org/', '');
          geonamesID = geonamesID.replace('https://www.geonames.org/', '');
          geonamesID = geonamesID.replace('http://geonames.org/', '');
          geonamesID = geonamesID.replace('https://geonames.org/', '');
          encodedURL = encodeURIComponent('http://api.geonames.org/getJSON?formatted=true&geonameId=' + geonamesID + '&username=' + geonames_username + '&style=full');
          callUrl = 'https://jsontojsonp.gbv.de/?url=' + encodedURL;
          deferred = new CUI.Deferred();
          extendedInfo_xhr = new CUI.XHR({
            url: callUrl
          });
          extendedInfo_xhr.start().done(function(data, status, statusText) {
            var cdataFromObjectsMap, k, len1, objectsMapKey, ref1, resultsUri, updatedcdata;
            if (data != null ? data.geonameId : void 0) {
              if (data != null ? data.asciiName : void 0) {
                resultsUri = 'http://geonames.org/' + data.geonameId;
                ref1 = objectsMap[originalUri];
                for (objectsMapKey = k = 0, len1 = ref1.length; k < len1; objectsMapKey = ++k) {
                  cdataFromObjectsMap = ref1[objectsMapKey];
                  cdataFromObjectsMap = cdataFromObjectsMap.data;
                  updatedcdata = {};
                  updatedcdata.conceptName = ez5.GeonamesUtil.getConceptNameFromObject(data);
                  updatedcdata.conceptURI = ez5.GeonamesUtil.getConceptURIFromObject(data);
                  updatedcdata._fulltext = ez5.GeonamesUtil.getFullTextFromObject(data, databaseLanguages);
                  updatedcdata._standard = ez5.GeonamesUtil.getStandardTextFromObject(null, data, cdataFromObjectsMap, databaseLanguages);
                  updatedcdata.conceptAncestors = ez5.GeonamesUtil.getConceptAncestorsFromObject(data);
                  if (that.__hasChanges(objectsMap[originalUri][objectsMapKey].data, updatedcdata)) {
                    objectsMap[originalUri][objectsMapKey].data = updatedcdata;
                    objectsToUpdate.push(objectsMap[originalUri][objectsMapKey]);
                  }
                }
              }
            }
            return deferred.resolve();
          }).fail(function() {
            return deferred.reject();
          });
          return deferred.promise();
        };
      })(this)
    });
    return chunkWorkPromise.done((function(_this) {
      return function() {
        return ez5.respondSuccess({
          payload: objectsToUpdate
        });
      };
    })(this)).fail((function(_this) {
      return function() {
        return ez5.respondError("custom.data.type.geonames.update.error.generic", {
          error: "Error connecting to geonames"
        });
      };
    })(this));
  };

  geonamesUpdate.prototype.__hasChanges = function(objectOne, objectTwo) {
    var j, key, len, ref;
    ref = ["conceptName", "conceptURI", "_standard", "_fulltext", "conceptAncestors", "frontendLanguage"];
    for (j = 0, len = ref.length; j < len; j++) {
      key = ref[j];
      if (!CUI.util.isEqual(objectOne[key], objectTwo[key])) {
        return true;
      }
    }
    return false;
  };

  geonamesUpdate.prototype.main = function(data) {
    var j, key, len, ref;
    if (!data) {
      ez5.respondError("custom.data.type.geonames.update.error.payload-missing");
      return;
    }
    ref = ["action", "server_config", "plugin_config"];
    for (j = 0, len = ref.length; j < len; j++) {
      key = ref[j];
      if (!data[key]) {
        ez5.respondError("custom.data.type.geonames.update.error.payload-key-missing", {
          key: key
        });
        return;
      }
    }
    if (data.action === "start_update") {
      this.__start_update(data);
    } else if (data.action === "update") {
      if (!data.objects) {
        ez5.respondError("custom.data.type.geonames.update.error.objects-missing");
        return;
      }
      if (!(data.objects instanceof Array)) {
        ez5.respondError("custom.data.type.geonames.update.error.objects-not-array");
        return;
      }
      if (!data.state) {
        ez5.respondError("custom.data.type.geonames.update.error.state-missing");
        return;
      }
      if (!data.batch_info) {
        ez5.respondError("custom.data.type.geonames.update.error.batch_info-missing");
        return;
      }
      this.__updateData(data);
    } else {
      return ez5.respondError("custom.data.type.geonames.update.error.invalid-action", {
        action: data.action
      });
    }
  };

  return geonamesUpdate;

})();

module.exports = new geonamesUpdate();
