var sys = require('util'),
    fs = require('fs');

var zoneinfo = require(__dirname + '/../index'),
    TZDate = zoneinfo.TZDate;

exports["listTimezones"] = function (test) {
    sys.puts(sys.inspect(zoneinfo.listTimezones('US')));
    test.done();
};

exports["date 1: basics"] = function (test) {
    var d = new TZDate("2010-09-21T03:18:23.000Z");

    test.equal(d.toString(), "2010-09-21 03:18:23 GMT", "toString");
    test.equal(d.format("Y-m-d"), "2010-09-21", "basic format");
    test.equal(d.getTimezone(), "UTC", "getTimezone");
    test.equal(d.getTimezone(true), "Etc/UTC", "getTimezone long");

    d.setTimezone("America/Denver");
    test.equal(d.toString(), "2010-09-20 21:18:23 GMT-0600", "changing timezone toString");
    test.equal(d.getTimezone(), "MDT", "changing timezone getTimezone");

    d.setTimezone("America/Phoenix");
    test.equal(d.toString(), "2010-09-20 20:18:23 GMT-0700", "changing timezone toString 2");
    test.equal(d.getTimezone(), "MST", "changing timezone getTimezone 2");
    test.done();
};

exports["date 2: advanced"] = function (test) {
    var symlinkFile = "/persist_storage/localtime";
    var ziRoot = "/usr/share/zoneinfo";
    var newZone = "America/New_York";
    try {
        fs.unlinkSync(symlinkFile)
    } catch(e){}

    zoneinfo.setDefaultTimezone(newZone);
    var lStat = fs.lstatSync(symlinkFile);
    test.ok(lStat.isSymbolicLink(), symlinkFile + " is a symlink");

    test.equal(fs.realpathSync(symlinkFile), fs.realpathSync(ziRoot + "/" + newZone), "Symlink should point to full path");

    var d = new TZDate("2010-11-08T16:00:00.000Z");
    test.equal(d.toString(), "2010-11-08 11:00:00 GMT-0500", "default timezone toString");
    test.equal(d.getTimezone(), "EST", "default timezone getTimezone");
    test.equal(d.getTimezone(true), "America/New_York", "default timezone getTimezone long");

    // Test overwriting symlink
    var newZone2 = "Africa/Abidjan";
    zoneinfo.setDefaultTimezone(newZone2);
    lStat = fs.lstatSync(symlinkFile);
    test.ok(lStat.isSymbolicLink(), symlinkFile + " is a symlink");

    test.equal(fs.realpathSync(symlinkFile), fs.realpathSync(ziRoot + "/" + newZone2), "Symlink should point to full path");

    test.done();
};

exports["date3: more advanced"] = function (test) {
    var d = new TZDate("05-20-1983 3:37 pm", "America/New_York");
    test.equal(d.toString(), "1983-05-20 15:37:00 GMT-0400", "timezone string locality");
    d.setTimezone("America/Los_Angeles");
    test.equal(d.toString(), "1983-05-20 12:37:00 GMT-0700", "timezone string locality after setTimezone");

    d = new TZDate("5-20-1983 15:37", "America/Chicago");
    test.equal(d.toString(), "1983-05-20 15:37:00 GMT-0500", "timezone string locality 2");
    d.setTimezone("America/Los_Angeles");
    test.equal(d.toString(), "1983-05-20 13:37:00 GMT-0700", "timezone string locality after setTimezone 2");


    test.done();
};

exports["date4: half hour timezones"] = function (test) {
    var d = new TZDate("05-20-1983 12:00 pm", "America/New_York");
    test.equal(d.toString(), "1983-05-20 12:00:00 GMT-0400", "Base date 1 for 1/2 hour timezone test");

    d.setTimezone("America/Caracas");
    test.equal(d.toString(), "1983-05-20 12:00:00 GMT-0400", "Old dates don't change");

    var d2 = new TZDate("02-20-2013 12:00 pm", "America/New_York");
    test.equal(d2.toString(), "2013-02-20 12:00:00 GMT-0500", "Base date 2 for 1/2 hour timezone test");

    d2.setTimezone("America/Caracas");
    test.equal(d2.toString(), "2013-02-20 12:30:00 GMT-0430", "New dates do change");

    test.done();
};

exports["timezones"] = function (test) {
    var us_timezones = ["America/Adak",
        "America/Anchorage",
        "America/Boise",
        "America/Chicago",
        "America/Denver",
        "America/Detroit",
        "America/Indiana/Indianapolis",
        "America/Indiana/Knox",
        "America/Indiana/Marengo",
        "America/Indiana/Petersburg",
        "America/Indiana/Tell_City",
        "America/Indiana/Vevay",
        "America/Indiana/Vincennes",
        "America/Indiana/Winamac",
        "America/Juneau",
        "America/Kentucky/Louisville",
        "America/Kentucky/Monticello",
        "America/Los_Angeles",
        "America/Menominee",
        "America/Metlakatla",
        "America/New_York",
        "America/Nome",
        "America/North_Dakota/Beulah",
        "America/North_Dakota/Center",
        "America/North_Dakota/New_Salem",
        "America/Phoenix",
        "America/Shiprock",
        "America/Sitka",
        "America/Yakutat",
        "Pacific/Honolulu"];

    test.equal(JSON.stringify(zoneinfo.listTimezones("US").sort()), JSON.stringify(us_timezones), "US timezone list");

    test.done();
};

exports["all-timezones-by-offset"] = function (test) {
    var zonesByOffset = zoneinfo.getTimezonesByOffset();
    var offsets = [];

    for (var prop in zonesByOffset) {
        if (zonesByOffset.hasOwnProperty(prop)) {
            offsets.push(prop);
            test.ok(prop.match(/^[+-]\d{4}$/), prop + " should look like +0000 or -0000");

            test.ok(zonesByOffset[prop], "Non-null zones for " + prop);

            test.ok(zonesByOffset[prop].length <= 5, "No more than five zones per offset for" + prop);

            var d = new zoneinfo.TZDate();
            zonesByOffset[prop].map(function(zone){
                d.setTimezone(zone);
                test.equal(d.getTimezone(true), zone, "Zone retrieved should match zone set, " + zone);

                test.equal(d.format("O"), prop, "Formatted offset should match offset of zones, " + zone);
            });
        }
    }
    offsets.sort();

    test.equal(offsets.length, 26, "26 Timezones");

    test.done();
};

exports["formatting"] = function (test) {
    var d = new TZDate("2010-09-21T03:18:23.000Z");
    var e = new TZDate("2010-10-01T14:31:01.001Z");
    var f = new TZDate("2010-10-01T00:31:01.001Z");
    var g = new TZDate("2010-10-01T12:31:01.001Z");
    d.setTimezone("Etc/UTC");
    e.setTimezone("Etc/UTC");
    f.setTimezone("Etc/UTC");
    g.setTimezone("Etc/UTC");

    test.equal(d.format("Y"), "2010", "format - Y");
    test.equal(d.format("m"), "09", "format - m");
    test.equal(e.format("m"), "10", "format - m 2");
    test.equal(d.format("n"), "9", "format - n");
    test.equal(e.format("n"), "10", "format - n 2");
    test.equal(d.format("d"), "21", "format - d");
    test.equal(e.format("d"), "01", "format - d 2");
    test.equal(d.format("j"), "21", "format - j");
    test.equal(e.format("j"), "1", "format - j 2");
    test.equal(d.format("F"), "September", "format - F");
    test.equal(e.format("F"), "October", "format - F 2");
    test.equal(d.format("M"), "Sep", "format - M");
    test.equal(e.format("M"), "Oct", "format - M 2");
    test.equal(d.format("l"), "Tuesday", "format - l");
    test.equal(e.format("l"), "Friday", "format - l 2");
    test.equal(d.format("D"), "Tue", "format - D");
    test.equal(e.format("D"), "Fri", "format - D 2");
    test.equal(d.format("H"), "03", "format - H");
    test.equal(e.format("H"), "14", "format - H 2");
    test.equal(d.format("h"), "03", "format - h");
    test.equal(e.format("h"), "02", "format - h 2");
    test.equal(f.format("h"), "12", "format - h 3");
    test.equal(g.format("h"), "12", "format - h 4");
    test.equal(d.format("G"), "3", "format - G");
    test.equal(e.format("G"), "14", "format - G 2");
    test.equal(d.format("g"), "3", "format - g");
    test.equal(e.format("g"), "2", "format - g 2");
    test.equal(f.format("g"), "12", "format - g 3");
    test.equal(g.format("g"), "12", "format - g 4");
    test.equal(d.format("i"), "18", "format - i");
    test.equal(e.format("i"), "31", "format - i 2");
    test.equal(d.format("s"), "23", "format - s");
    test.equal(e.format("s"), "01", "format - s 2");
    test.equal(d.format("A"), "AM", "format - A");
    test.equal(e.format("A"), "PM", "format - A 2");
    test.equal(d.format("a"), "am", "format - a");
    test.equal(e.format("a"), "pm", "format - a 2");
    test.equal(d.format("T"), "UTC", "format - T");
    test.equal(e.format("T"), "UTC", "format - T 2");
    test.equal(d.format("t"), "Etc/UTC", "format - t");
    test.equal(e.format("t"), "Etc/UTC", "format - t 2");
    test.equal(d.format("O"), "+0000", "format - O");
    test.equal(e.format("O"), "+0000", "format - O 2");


    test.done();
};

exports["issue 2"] = function (test) {
    var t1 = function () {
        var local_date = new TZDate(Date.now());
        local_date.setTimezone("America/Chicago");
    }

    var noThrow = true;

    try {
        t1()
    }
    catch (ex) {
        noThrow = false;
    }

    test.equal(noThrow, true, "timestamp passing")

    test.done();
};
