var noun_prefix = "noun";
var adjective_prefix = "adjective";
var count_key_suffix = "_count";

function random_int(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}

function random_choice(array) {
  return array[random_int(0, array.length)];
}

function probability(p) {
  return Math.random() < p;
}

function chain(fns) {
  if (fns.length == 0) {
    return;
  }
  return fns[0](function() { chain(fns.slice(1)) });
}

function render_status(statusText) {
  document.getElementById('status').textContent = statusText;
}

function get_local_entry(names, callback) {
  console.log("Fetching " + names + " from local storage");
  chrome.storage.local.get(
    names,
    function(result) {
      console.log("Fetched " + JSON.stringify(result));
      callback(result);
    }
  );
}

function set_local_entry(entry, callback) {
  chrome.storage.local.set(entry, callback);
}

function with_file_entry(dir_entry, filename, callback) {
  dir_entry.getFile(
    filename,
    undefined,
    callback,
    function (e) { console.log("Error getting file: " + e); }
  );
}

function with_file(dir_entry, filename, callback) {
  with_file_entry(dir_entry, filename, function (file_entry) { file_entry.file(callback); });
}

function with_file_contents(dir_entry, filename, callback) {
  with_file(
    dir_entry,
    filename,
    function (file) {
      var reader = new FileReader();
      reader.addEventListener(
        "load",
        function (event) {
          callback(reader.result);
        }
      );
      reader.readAsText(file);
    }
  );
}

function populate_from_prefix(dir, filename, count_key, prefix, callback) {
  with_file_contents(
    dir,
    filename,
    function (contents) {
      var split_contents = contents.split("\r\n");
      var entry = {};
      entry[count_key] = split_contents.length;
      for (var i = 0; i < split_contents.length; ++i) {
        entry[prefix + i] = split_contents[i];
      }
      set_local_entry(entry, callback);
    }
  );
}

function populate_local_storage(callback) {
  chrome.runtime.getPackageDirectoryEntry(
    function (dir) {
      chain([
        function(c) { populate_from_prefix(dir, "nouns.txt", noun_prefix + count_key_suffix, noun_prefix, c); },
        function(c) { populate_from_prefix(dir, "adjectives.txt", adjective_prefix + count_key_suffix, adjective_prefix, c); },
        callback
      ]);
    }
  );
}

function ensure_local_storage_is_populated(callback) {
  console.log("Checking whether local storage is populated..");
  get_local_entry(
    [noun_prefix + count_key_suffix, adjective_prefix + count_key_suffix],
    function(counts) {
      if (chrome.runtime.lastError || Object.keys(counts).length < 2) {
        console.log("Couldn't retrieve dictionary from local storage; repopulating it..");
        populate_local_storage(callback);
      }
      console.log("Local storage is populated!");
      callback();
    }
  );
}

function capitalize(s) {
  return s.charAt(0).toUpperCase() + s.slice(1);
}

function random_word(prefix, callback) {
  var count_key = prefix + count_key_suffix;
  get_local_entry(
    count_key,
    function(count_entry) {
      var count = count_entry[count_key];
      var idx = random_int(0, count);
      var word_key = prefix + idx;
      get_local_entry(
        word_key,
        function(word_entry) {
          callback(word_entry[word_key]);
        }
      );
    }
  );
}

function choose_prefix() {
  if (probability(1/3)) {
    if (probability(1/3)) {
      return "a";
    }
    return "the";
  }
  return "";
}

function create_suffix() {
  var length = random_int(0, 4);
  var suffix = "";
  for (var i = 0; i < length; ++i) {
    suffix += random_choice("1234567890");
  }
  return suffix;
}

function generate_phrase_name(callback) {
  console.log("Generating phrase name");
  random_word(noun_prefix, function(noun) {
  random_word(adjective_prefix, function(adjective) {
    var prefix = choose_prefix();
    var suffix = create_suffix();

    var name;
    if (Math.random() < 0.5) {
      prefix = capitalize(prefix);
      adjective = capitalize(adjective);
      noun = capitalize(noun);
      name = prefix + adjective + noun;
    } else {
      prefix = prefix.toLowerCase();
      adjective = adjective.toLowerCase();
      noun = noun.toLowerCase();

      if (prefix == "") {
        name = adjective + "_" + noun + suffix;
      } else {
        name =  prefix + "_" + adjective + "_" + noun + suffix;
      }
    }
    if (name.length <= 20) {
      render_status("Your brand new name is:\n" + name);
      callback();
    } else {
      generate_phrase_name(callback);
    }
  })});
}

function generate_gibberish_name(callback) {
  var length = 6 + random_int(0, 4) + random_int(0, 4) + random_int(0, 4);
  console.log("Generating gibberish name with length " + length);
  var name = "";
  for(var i = 0; i < length; ++i) {
    name += random_choice("1234567890-qwertyuiopasdfghjklzxcvbnm");
  }
  console.log(name);
  render_status("Your brand new name is:\n" + name);
  callback();
}

function generate_name(callback) {
  var p = Math.random();
  p -= 1/2;
  if (p < 0) {
    generate_phrase_name(callback);
    return;
  }

  generate_gibberish_name(callback);
}

document.addEventListener('DOMContentLoaded',
  function() {
    console.log("Popup page loaded");
    chain([
      ensure_local_storage_is_populated,
      generate_name
    ]);
  }
);
