const { SearchTestUtils } = ChromeUtils.importESModule(
  "resource://testing-common/SearchTestUtils.sys.mjs"
);

SearchTestUtils.init(this);

function getCellText(tree, i, cellName) {
  return tree.view.getCellText(i, tree.columns.getNamedColumn(cellName));
}

add_setup(async function () {
  await SearchTestUtils.installSearchExtension({
    keyword: ["testing", "customkeyword"],
    search_url: "https://example.com/engine1",
    search_url_get_params: "search={searchTerms}",
  });
});

add_task(async function test_engine_list() {
  let prefs = await openPreferencesViaOpenPreferencesAPI("search", {
    leaveOpen: true,
  });
  is(prefs.selectedPane, "paneSearch", "Search pane is selected by default");
  let doc = gBrowser.contentDocument;

  let tree = doc.querySelector("#engineList");
  ok(
    !tree.hidden,
    "The search engine list should be visible when Search is requested"
  );

  // Check for default search engines to be displayed in the engineList
  let defaultEngines = await Services.search.getAppProvidedEngines();
  for (let i = 0; i < defaultEngines.length; i++) {
    let engine = defaultEngines[i];
    is(
      getCellText(tree, i, "engineName"),
      engine.name,
      "Default search engine " + engine.name + " displayed correctly"
    );
  }

  let customEngineIndex = defaultEngines.length;
  is(
    getCellText(tree, customEngineIndex, "engineKeyword"),
    "testing, customkeyword",
    "Show internal aliases"
  );

  // Scroll the treeview into view since mouse operations
  // off screen can act confusingly.
  tree.scrollIntoView();
  let rect = tree.getCoordsForCellItem(
    customEngineIndex,
    tree.columns.getNamedColumn("engineKeyword"),
    "text"
  );
  let x = rect.x + rect.width / 2;
  let y = rect.y + rect.height / 2;
  let win = tree.ownerGlobal;

  let promise = BrowserTestUtils.waitForEvent(tree, "dblclick");
  EventUtils.synthesizeMouse(tree.body, x, y, { clickCount: 1 }, win);
  EventUtils.synthesizeMouse(tree.body, x, y, { clickCount: 2 }, win);
  await promise;

  EventUtils.sendString("newkeyword");
  EventUtils.sendKey("RETURN");

  await TestUtils.waitForCondition(() => {
    return (
      getCellText(tree, customEngineIndex, "engineKeyword") ===
      "newkeyword, testing, customkeyword"
    );
  });

  // Avoid duplicated keywords
  tree.view.setCellText(
    0,
    tree.columns.getNamedColumn("engineKeyword"),
    "keyword"
  );
  tree.view.setCellText(
    1,
    tree.columns.getNamedColumn("engineKeyword"),
    "keyword"
  );
  isnot(
    getCellText(tree, 1, "engineKeyword"),
    "keyword",
    "Do not allow duplicated keywords"
  );

  BrowserTestUtils.removeTab(gBrowser.selectedTab);
});

add_task(async function test_remove_button_disabled_state() {
  let prefs = await openPreferencesViaOpenPreferencesAPI("search", {
    leaveOpen: true,
  });
  is(prefs.selectedPane, "paneSearch", "Search pane is selected by default");
  let doc = gBrowser.contentDocument;

  let tree = doc.querySelector("#engineList");
  ok(
    !tree.hidden,
    "The search engine list should be visible when Search is requested"
  );

  let defaultEngines = await Services.search.getAppProvidedEngines();
  for (let i = 0; i < defaultEngines.length; i++) {
    let engine = defaultEngines[i];

    let isDefaultSearchEngine =
      engine.name == Services.search.defaultEngine.name ||
      engine.name == Services.search.defaultPrivateEngine.name;

    tree.scrollIntoView();
    let rect = tree.getCoordsForCellItem(
      i,
      tree.columns.getNamedColumn("engineName"),
      "text"
    );
    let x = rect.x + rect.width / 2;
    let y = rect.y + rect.height / 2;
    let win = tree.ownerGlobal;

    let promise = BrowserTestUtils.waitForEvent(tree, "click");
    EventUtils.synthesizeMouse(tree.body, x, y, { clickCount: 1 }, win);
    await promise;

    let removeButton = doc.querySelector("#removeEngineButton");
    is(
      removeButton.disabled,
      isDefaultSearchEngine,
      "Remove button is in correct disable state"
    );
  }

  BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
