// Test --host.
(function() {
// This "inner_mode" method of spawning a mongod and re-running was copied from
// ipv6_connection_string_validation.js
if ("undefined" == typeof inner_mode) {
    // Start a mongod with --ipv6
    jsTest.log("Outer mode test starting mongod with --ipv6");
    // NOTE: bind_ip arg is present to test if it can parse ipv6 addresses (::1 in this case).
    // Unfortunately, having bind_ip = ::1 won't work in the test framework (But does work when
    // tested manually), so 127.0.0.1 is also present so the test mongo shell can connect
    // with that address.
    var mongod = MongoRunner.runMongod({ipv6: "", bind_ip: "::1,127.0.0.1"});
    if (mongod == null) {
        jsTest.log("Unable to run test because ipv6 is not on machine, see BF-10990");
        return;
    }
    var args = [
        "mongo",
        "--nodb",
        "--ipv6",
        "--host",
        "::1",
        "--port",
        mongod.port,
        "--eval",
        "inner_mode=true;port=" + mongod.port + ";",
        "jstests/noPassthroughWithMongod/host_connection_string_validation.js"
    ];
    var exitCode = _runMongoProgram.apply(null, args);
    jsTest.log("Inner mode test finished, exit code was " + exitCode);

    MongoRunner.stopMongod(mongod);
    // Pass the inner test's exit code back as the outer test's exit code
    if (exitCode != 0) {
        doassert("inner test failed with exit code " + exitCode);
    }
    return;
}

var testHost = function(host, shouldSucceed) {
    var exitCode = runMongoProgram('mongo', '--ipv6', '--eval', ';', '--host', host);
    if (shouldSucceed) {
        if (exitCode !== 0) {
            doassert("failed to connect with `--host " + host +
                     "`, but expected success. Exit code: " + exitCode);
        }
    } else {
        if (exitCode === 0) {
            doassert("successfully connected with `--host " + host + "`, but expected to fail.");
        }
    }
};

var goodStrings = [
    "[::1]:27999",
    "localhost:27999",
    "127.0.0.1:27999",
    "[0:0:0:0:0:0:0:1]:27999",
    "[0000:0000:0000:0000:0000:0000:0000:0001]:27999",
];

var goodSocketStrings = [
    "/tmp/mongodb-27999.sock",
];

var badStrings = [
    "::1:27999",
    "::1:65536",
    "::1]:27999",
    ":",
    ":27999",
    "[::1:]27999",
    "[::1:27999",
    "[::1]:",
    "[::1]:123456",
    "[::1]:1cat",
    "[::1]:65536",
    "[::1]:cat",
    "0:0::0:0:1:27999",
    "0000:0000:0000:0000:0000:0000:0000:0001:27999",
    "127.0.0.1:",
    "127.0.0.1:123456",
    "127.0.0.1:1cat",
    "127.0.0.1:65536",
    "127.0.0.1:cat",
    "a[::1:]27999",
    "a[127.0.0.1]:27999",
    "localhost:",
];

function runUriTestFor(i, connectionString, isGood) {
    connectionString = connectionString.replace("27999", "" + port);
    print("Testing " + (isGood ? "good" : "bad") + " connection string " + i + "...");
    print("    * testing " + connectionString);
    testHost(connectionString, isGood);
    print("    * testing mongodb://" + encodeURIComponent(connectionString));
    testHost("mongodb://" + encodeURIComponent(connectionString), isGood);
}

var i;
jsTest.log("TESTING " + goodStrings.length + " good uri strings");
for (i = 0; i < goodStrings.length; ++i) {
    runUriTestFor(i, goodStrings[i], true);
}

if (!_isWindows()) {
    jsTest.log("TESTING " + goodSocketStrings.length + " good uri socket strings");
    for (i = 0; i < goodSocketStrings.length; ++i) {
        runUriTestFor(i, goodSocketStrings[i], true);
    }
}

jsTest.log("TESTING " + badStrings.length + " bad uri strings");
for (i = 0; i < badStrings.length; ++i) {
    runUriTestFor(i, badStrings[i], false);
}

jsTest.log("SUCCESSFUL test completion");
})();
