/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

const SEARCH_SERVICE_TOPIC = "browser-search-service";
const SEARCH_ENGINE_TOPIC = "browser-search-engine-modified";

const CONFIG = [
  {
    identifier: "everywhereExceptFRRegion",
    variants: [{ environment: { excludedRegions: ["FR"] } }],
  },
  {
    identifier: "everywhereEngine",
    variants: [{ environment: { allRegionsAndLocales: true } }],
  },
  {
    specificDefaults: [
      {
        default: "everywhereExceptFRRegion",
        defaultPrivate: "everywhereExceptFRRegion",
        environment: { excludedRegions: ["FR"] },
      },
      {
        default: "everywhereEngine",
        defaultPrivate: "everywhereEngine",
        environment: { regions: ["FR"] },
      },
    ],
  },
];

// Default engine with no region defined.
const DEFAULT = "everywhereExceptFRRegion";
// Default engine with region set to FR.
const FR_DEFAULT = "everywhereEngine";

function listenFor(name, key) {
  let notifyObserved = false;
  let obs = (subject, topic, data) => {
    if (data == key) {
      notifyObserved = true;
    }
  };
  Services.obs.addObserver(obs, name);

  return () => {
    Services.obs.removeObserver(obs, name);
    return notifyObserved;
  };
}

add_setup(async function () {
  Services.prefs.setBoolPref("browser.search.separatePrivateDefault", true);
  Services.prefs.setBoolPref(
    SearchUtils.BROWSER_SEARCH_PREF + "separatePrivateDefault.ui.enabled",
    true
  );

  SearchTestUtils.useMockIdleService();
  SearchTestUtils.setRemoteSettingsConfig(CONFIG);
});

// This tests what we expect is the normal startup route for a fresh profile -
// the search service initializes with no region details, then gets a region
// notified part way through / afterwards.
add_task(async function test_initialization_with_region() {
  let reloadObserved = listenFor(SEARCH_SERVICE_TOPIC, "engines-reloaded");
  let initPromise;

  // Ensure the region lookup completes after init so the
  // engines are reloaded
  let srv = useHttpServer();
  srv.registerPathHandler("/fetch_region", async (req, res) => {
    res.processAsync();
    await initPromise;
    res.setStatusLine("1.1", 200, "OK");
    res.write(JSON.stringify({ country_code: "FR" }));
    res.finish();
  });

  Services.prefs.setCharPref(
    "browser.region.network.url",
    `http://localhost:${srv.identity.primaryPort}/fetch_region`
  );

  Region._setHomeRegion("", false);
  Region.init();

  initPromise = SearchService.init();
  await initPromise;

  let otherPromises = [
    // This test expects settings to be saved twice.
    promiseAfterSettings().then(promiseAfterSettings),
    SearchTestUtils.promiseSearchNotification(
      "engine-default",
      SEARCH_ENGINE_TOPIC
    ),
  ];

  Assert.equal(
    SearchService.defaultEngine.name,
    DEFAULT,
    "Test engine shouldn't be the default anymore"
  );

  await Promise.all(otherPromises);

  // Ensure that correct engine is being reported as the default.
  Assert.equal(
    SearchService.defaultEngine.name,
    FR_DEFAULT,
    "everywhereEngine should be the default in FR"
  );
  Assert.equal(
    (await SearchService.getDefaultPrivate()).name,
    FR_DEFAULT,
    "everywhereEngine should be the private default in FR"
  );

  Assert.ok(reloadObserved(), "Engines do reload with delayed region fetch");
});
