"use strict";

const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;

function getFileURI(path) {
  let file = do_get_file(".");
  file.append(path);
  return Services.io.newFileURI(file);
}

add_task(async function() {
  const registry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry);

  let file1 = getFileURI("file1");
  let file2 = getFileURI("file2");

  let uri1 = getFileURI("chrome.manifest");
  let uri2 = getFileURI("manifest.json");

  let overrideURL = Services.io.newURI("chrome://global/content/foo");
  let localeURL = Services.io.newURI("chrome://global/locale/foo");

  let origOverrideURL = registry.convertChromeURL(overrideURL);
  let origLocaleURL = registry.convertChromeURL(localeURL);

  // eslint-disable-next-line no-unused-vars
  let entry1 = aomStartup.registerChrome(uri1, [
    ["override", "chrome://global/content/foo", file1.spec],
    ["locale", "global", "en-US", file2.spec + "/"],
  ]);

  let entry2 = aomStartup.registerChrome(uri2, [
    ["override", "chrome://global/content/foo", file2.spec],
    ["locale", "global", "en-US", file1.spec + "/"],
  ]);

  // Initially, the second entry should override the first.
  equal(registry.convertChromeURL(overrideURL).spec, file2.spec);
  equal(registry.convertChromeURL(localeURL).spec, file1.spec + "/foo");

  // After destroying the second entry, the first entry should not take
  // precedence.
  entry2.destruct();
  equal(registry.convertChromeURL(overrideURL).spec, file1.spec);
  equal(registry.convertChromeURL(localeURL).spec, file2.spec + "/foo");

  // After dropping the reference to the first entry and allowing it to
  // be GCed, we should be back to the original entries.
  entry1 = null;
  Cu.forceGC();
  Cu.forceCC();
  equal(registry.convertChromeURL(overrideURL).spec, origOverrideURL.spec);
  equal(registry.convertChromeURL(localeURL).spec, origLocaleURL.spec);
});

add_task(async function() {
  const INVALID_VALUES = [
    {},
    "foo",
    ["foo"],
    [{}],
    [[]],
    [["content", "foo", "bar"]],
    [["locale", "global"]],
    [["locale", "global", "en", "foo", "foo"]],
    [["override", "en"]],
    [["override", "en", "US", "OR"]],
  ];

  let uri = getFileURI("chrome.manifest");
  for (let arg of INVALID_VALUES) {
    Assert.throws(() => aomStartup.registerChrome(uri, arg),
                  e => e.result == Cr.NS_ERROR_INVALID_ARG,
                  `Arg ${uneval(arg)} should throw`);
  }
});
