
// Navicenter A/B Test
(function() {
    try {
        var zfcNavicenterABRate = typeof(window.zfcNavicenterABRate) !== 'undefined' ? window.zfcNavicenterABRate : null;
        var zfcNavTestName = typeof(window.zfcNavTestName) !== 'undefined' ? window.zfcNavTestName : null;
        
        var NAVICENTER_AB_RATE = zfcNavicenterABRate || Number("0.1");
        var NAV_TEST_NAME = zfcNavTestName || "www-nav-10";
        
        var chance = NAVICENTER_AB_RATE || 0;
        if (!chance) return; // if chance is 0, don't continue.
    } catch (e) {
        // If any errors with the above, just return
        return;
    }
    /**
    *
    *  Base64 encode / decode
    *  http://www.webtoolkit.info/
    *
    **/
    var Base64 = {
        // private property
        _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

        // public method for encoding
        encode : function (input) {
            var output = "";
            var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
            var i = 0;

            while (i < input.length) {

                chr1 = input.charCodeAt(i++);
                chr2 = input.charCodeAt(i++);
                chr3 = input.charCodeAt(i++);

                enc1 = chr1 >> 2;
                enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                enc4 = chr3 & 63;

                if (isNaN(chr2)) {
                    enc3 = enc4 = 64;
                } else if (isNaN(chr3)) {
                    enc4 = 64;
                }

                output = output +
                this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
                this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

            }

            return output;
        },

        // public method for decoding
        decode : function (input) {
            var output = "";
            var chr1, chr2, chr3;
            var enc1, enc2, enc3, enc4;
            var i = 0;

            input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

            while (i < input.length) {

                enc1 = this._keyStr.indexOf(input.charAt(i++));
                enc2 = this._keyStr.indexOf(input.charAt(i++));
                enc3 = this._keyStr.indexOf(input.charAt(i++));
                enc4 = this._keyStr.indexOf(input.charAt(i++));

                chr1 = (enc1 << 2) | (enc2 >> 4);
                chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                chr3 = ((enc3 & 3) << 6) | enc4;

                output = output + String.fromCharCode(chr1);

                if (enc3 != 64) {
                    output = output + String.fromCharCode(chr2);
                }
                if (enc4 != 64) {
                    output = output + String.fromCharCode(chr3);
                }

            }

            return output;
        }
    };

    this.ZFCCookie = {
        decode: function(data) {
            if (!data || data == "") return [];
            zfc = Base64.decode(data);

            var skipLength = zfc.charCodeAt(1) + 2; // +2 for offset, +1 to skip 2nd field marker
            var pointer = skipLength;

            // for (var i = 0; i < zfc.length; i++)
            //   console.log(zfc.charCodeAt(i));

            var testObjs = [];

            while (pointer < zfc.length) {
                pointer += 2; // Skip the Test marker and the length
                if (pointer >= zfc.length) {
                    console.warn("Protobuf parsing failed -- after skipping repeat marker and length we are past the length of the data.");
                    break;
                } else if (zfc.charCodeAt(pointer) != 10) {
                    console.warn("Protobuf parsing was inconsistent -- Expected encoding of 10 got: " + zfc.charCodeAt(pointer));
                    break;
                }
                pointer++; // Move passed the string marker

                var test = {};

                var strLen = zfc.charCodeAt(pointer); // Read the string (Test Name) length
                pointer++; // Now we should be on the first character of the string (Test Name)

                test.name = zfc.substring(pointer, pointer+strLen); // Substring out the Test Name
                pointer += strLen; // Now we are either at the end of the Test or sitting on the Test Index value

                if (pointer < zfc.length) { // If false, we are done with this Test object
                    if (zfc.charCodeAt(pointer) == 16) { // If this is true that means we have an Index field
                        pointer++; // Skip the marker
                        test.value = zfc.charCodeAt(pointer); // Read the Index field value
                        pointer++; // Move passed the Index field
                    }
                }

            testObjs.push(test);
            }

            return {data: zfc, tests: testObjs};
        },

        addTest: function(data, name, value) {
            if (value instanceof Number && value > 0 && value < 128) {
                console.warn("Value must be between 0 and 128.");
                return data;
            }

            var length = name.length + 4;
            if (length > 128) {
                console.warn("Length of name is too long, must be less than 124 chars");
                return data;
            }

            var buffer = "";
            buffer += String.fromCharCode(18); // Test Object Marker
            buffer += String.fromCharCode(length);  // Length of Test Object

            buffer += String.fromCharCode(10); // Test Name Marker
            buffer += String.fromCharCode(name.length); // Length of name
            buffer += name;

            buffer += String.fromCharCode(16); // Test Value Marker
            buffer += String.fromCharCode(value);

            return data + buffer;
        }
    }
    
    
    try { // This can break if the ZFC Cookie changes in unexpected ways.
        // if zfcUPU (Upstream URL) exists, use it. Else, use the natural browser's location.
        var UPU = (typeof(zfcUPU) != "undefined") ? zfcUPU : document.location.pathname;
        console.time("ZFC STUFF");
        if (typeof(UPU) == "string" && /^\/search/.exec(UPU)) {
            var zfcCookie = Cookie.read("zfc", {encode: false});
            if (zfcCookie && zfcCookie != "") {
                var zfc = ZFCCookie.decode(zfcCookie);
                var navTest = null;
                for (var i = 0; i < zfc.tests.length; i++) {
                    if (zfc.tests[i].name === NAV_TEST_NAME) {
                        navTest = zfc.tests[i];
                        break;
                    }
                }
            
                if (!navTest) {
                    navTest = {"name": NAV_TEST_NAME};
                    if (Math.random() < chance) {
                        var newCookie = Base64.encode(ZFCCookie.addTest(zfc.data, NAV_TEST_NAME, 2));
                        navTest.value = 2;
                        Cookie.write("zfc", newCookie, {path: '/', domain: '.zappos.com', duration: 3650, encode: false});
                    } else {
                        var newCookie = Base64.encode(ZFCCookie.addTest(zfc.data, NAV_TEST_NAME, 1));
                        navTest.value = 1;
                        Cookie.write("zfc", newCookie, {path: '/', domain: '.zappos.com', duration: 3650, encode: false});
                    }
                }
            
                if (navTest.value == 2 && /^\/search(?:[^0-9]|$)/.exec(UPU)) {
                    location.replace(UPU.replace(/search/, "search2"));
                    return true;
                }
            }
        }
    } catch (e) {
        console.warn(e.message);
    }
    console.timeEnd("ZFC STUFF");
})();