"use strict";

// Some test machines and android are not returning ipv6, turn it
// off to get consistent test results.
Services.prefs.setBoolPref("network.dns.disableIPv6", true);

function getExtension(background = undefined) {
  let manifest = {
    "permissions": [
      "dns",
    ],
  };
  return ExtensionTestUtils.loadExtension({
    manifest,
    background() {
      browser.test.onMessage.addListener(async (msg, data) => {
        browser.test.log(`=== dns resolve test ${JSON.stringify(data)}`);
        browser.dns.resolve(data.hostname, data.flags).then(result => {
          browser.test.log(`=== dns resolve result ${JSON.stringify(result)}`);
          browser.test.sendMessage("resolved", result);
        }).catch(e => {
          browser.test.log(`=== dns resolve error ${e.message}`);
          browser.test.sendMessage("resolved", {message: e.message});
        });
      });
      browser.test.sendMessage("ready");
    },
  });
}

const tests = [
  {
    request: {
      hostname: "localhost",
    },
    expect: {
      addresses: ["127.0.0.1"], // ipv6 disabled , "::1"
    },
  },
  {
    request: {
      hostname: "localhost",
      flags: ["offline"],
    },
    expect: {
      addresses: ["127.0.0.1"], // ipv6 disabled , "::1"
    },
  },
  {
    request: {
      hostname: "test.example",
    },
    expect: {
      // android will error with offline
      error: /NS_ERROR_UNKNOWN_HOST|NS_ERROR_OFFLINE/,
    },
  },
  {
    request: {
      hostname: "127.0.0.1",
      flags: ["canonical_name"],
    },
    expect: {
      canonicalName: "127.0.0.1",
      addresses: ["127.0.0.1"],
    },
  },
  {
    request: {
      hostname: "localhost",
      flags: ["disable_ipv6"],
    },
    expect: {
      addresses: ["127.0.0.1"],
    },
  },
];

add_task(async function test_dns_resolve() {
  let extension = getExtension();
  await extension.startup();
  await extension.awaitMessage("ready");

  for (let test of tests) {
    extension.sendMessage("resolve", test.request);
    let result = await extension.awaitMessage("resolved");
    if (test.expect.error) {
      ok(test.expect.error.test(result.message), `expected error ${result.message}`);
    } else {
      equal(result.canonicalName, test.expect.canonicalName, "canonicalName match");
      // It seems there are platform differences happening that make this
      // testing difficult. We're going to rely on other existing dns tests to validate
      // the dns service itself works and only validate that we're getting generally
      // expected results in the webext api.
      ok(result.addresses.length >= test.expect.addresses.length, "expected number of addresses returned");
      if (test.expect.addresses.length > 0 && result.addresses.length > 0) {
        ok(result.addresses.includes(test.expect.addresses[0]), "got expected ip address");
      }
    }
  }

  await extension.unload();
});
