// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

function cacheBust() {
    return "?anti-cache=" + String(Math.round(Math.random() * 1000000));
};

couchTests.attachment_ranges = function(debug) {
    var db_name = get_random_db_name();
    var db = new CouchDB(db_name, {
        "X-Couch-Full-Commit": "false"
    });
    db.createDb();

    if (debug) debugger;

    if((typeof window != "undefined") && window.navigator.userAgent.match(/Chrome/)) {
        // Chrome is broken.
        return;
    }

    var binAttDoc = {
        _id: "bin_doc",
        _attachments: {
            "foo.txt": {
                content_type: "application/octet-stream",
                data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
            }
        }
    };

    var save_response = db.save(binAttDoc);
    T(save_response.ok);

    // Fetching the whole entity is a 206.
    var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
        headers: {
            "Range": "bytes=0-28"
        }
    });
    TEquals(206, xhr.status, "fetch 0-28");
    TEquals("This is a base64 encoded text", xhr.responseText);
    TEquals("bytes 0-28/29", xhr.getResponseHeader("Content-Range"));
    TEquals("29", xhr.getResponseHeader("Content-Length"));

    // Fetch the whole entity without an end offset is a 200.
    var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
        headers: {
            "Range": "bytes=0-"
        }
    });
    TEquals(200, xhr.status, "fetch 0-");
    TEquals("This is a base64 encoded text", xhr.responseText);
    TEquals(null, xhr.getResponseHeader("Content-Range"));
    TEquals("29", xhr.getResponseHeader("Content-Length"));

    // Even if you ask multiple times.
    var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
        headers: {
            "Range": "bytes=0-,0-,0-"
        }
    });
    TEquals(200, xhr.status, "multiple 0-'s");

    // Badly formed range header is a 200.
    var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
        headers: {
            "Range": "bytes:0-"
        }
    });
    TEquals(200, xhr.status, "fetch with bad range header");

    // Fetch the end of an entity without an end offset is a 206.
    var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt"  + cacheBust(), {
        headers: {
            "Range": "bytes=2-"
        }
    });
    TEquals(206, xhr.status, "fetch 2-");
    TEquals("is is a base64 encoded text", xhr.responseText);
    TEquals("bytes 2-28/29", xhr.getResponseHeader("Content-Range"));
    TEquals("27", xhr.getResponseHeader("Content-Length"));

    // Fetch past the end of the entity is a 206
    var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt"  + cacheBust(), {
        headers: {
            "Range": "bytes=0-29"
        }
    });
    TEquals(206, xhr.status, "fetch 0-29");
    TEquals("bytes 0-28/29", xhr.getResponseHeader("Content-Range"));
    TEquals("29", xhr.getResponseHeader("Content-Length"));

    // Fetch first part of entity is a 206
    var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
        headers: {
            "Range": "bytes=0-3"
        }
    });
    TEquals(206, xhr.status, "fetch 0-3");
    TEquals("This", xhr.responseText);
    TEquals("4", xhr.getResponseHeader("Content-Length"));
    TEquals("bytes 0-3/29", xhr.getResponseHeader("Content-Range"));

    // Fetch middle of entity is also a 206
    var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
        headers: {
            "Range": "bytes=10-15"
        }
    });
    TEquals(206, xhr.status, "fetch 10-15");
    TEquals("base64", xhr.responseText);
    TEquals("6", xhr.getResponseHeader("Content-Length"));
    TEquals("bytes 10-15/29", xhr.getResponseHeader("Content-Range"));

    // Fetch end of entity is also a 206
    var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
        headers: {
            "Range": "bytes=-3"
        }
    });
    TEquals(206, xhr.status, "fetch -3");
    TEquals("ext", xhr.responseText);
    TEquals("3", xhr.getResponseHeader("Content-Length"));
    TEquals("bytes 26-28/29", xhr.getResponseHeader("Content-Range"));
    
    // backward range is 416
    var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
       headers: {
           "Range": "bytes=5-3"
       }
    });
    TEquals(416, xhr.status, "fetch 5-3");

    // range completely outside of entity is 416
    var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
        headers: {
            "Range": "bytes=300-310"
        }
    });
    TEquals(416, xhr.status, "fetch 300-310");

    // We ignore a Range header with too many ranges
    var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
        headers: {
            "Range": "bytes=0-1,0-1,0-1,0-1,0-1,0-1,0-1,0-1,0-1,0-1"
        }
    });
    TEquals(200, xhr.status, "too many ranges");
    // cleanup
    db.deleteDb();

};
