// 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.

couchTests.view_errors = 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;

  // run_on_modified_server(
  //   [{section: "couchdb",
  //     key: "os_process_timeout",
  //     value: "500"}],
  //   function() {
      var doc = {integer: 1, string: "1", array: [1, 2, 3]};
      T(db.save(doc).ok);

      // emitting a key value that is undefined should result in that row
      // being included in the view results as null
      var results = db.query(function(doc) {
        emit(doc.undef, null);
      });
      T(results.total_rows == 1);
      T(results.rows[0].key == null);

      // if a view function throws an exception, its results are not included in
      // the view index, but the view does not itself raise an error
      var results = db.query(function(doc) {
        doc.undef(); // throws an error
      });
      T(results.total_rows == 0);

      // if a view function includes an undefined value in the emitted key or
      // value, it is treated as null
      var results = db.query(function(doc) {
        emit([doc._id, doc.undef], null);
      });
      T(results.total_rows == 1);
      T(results.rows[0].key[1] == null);
      
      // querying a view with invalid params should give a resonable error message
      var xhr = CouchDB.request("POST", "/" + db_name + "/_all_docs?startkey=foo", {
        headers: {"Content-Type": "application/json"},
        body: JSON.stringify({language: "javascript",
          map : "function(doc){emit(doc.integer)}"
        })
      });
      T(JSON.parse(xhr.responseText).error == "bad_request");

      // content type must be json
      var xhr = CouchDB.request("POST", "/" + db_name + "/_all_docs", {
        headers: {"Content-Type": "application/x-www-form-urlencoded"},
        body: JSON.stringify({language: "javascript",
          map : "function(doc){}"
        })
      });
      T(xhr.status == 415);

      var map = function (doc) {emit(doc.integer, doc.integer);};

      try {
          db.query(map, null, {group: true});
          T(0 == 1);
      } catch(e) {
          T(e.error == "query_parse_error");
      }

      var designDoc = {
        _id:"_design/test",
        language: "javascript",
        views: {
          "no_reduce": {map:"function(doc) {emit(doc._id, null);}"},
          "with_reduce": {
            map:"function (doc) {emit(doc.integer, doc.integer)};",
            reduce:"function (keys, values) { return sum(values); };"}
        }
      };
      T(db.save(designDoc).ok);

      var designDoc2 = {
        _id:"_design/testbig",
        language: "javascript",
        views: {
          "reduce_too_big"  : {
            map:"function (doc) {emit(doc.integer, doc.integer)};",
            reduce:"function (keys, values) { var chars = []; for (var i=0; i < 1000; i++) {chars.push('wazzap');};return chars; };"}
        }
      };
      T(db.save(designDoc2).ok);

      try {
          db.view("test/no_reduce", {group: true});
          T(0 == 1);
      } catch(e) {
          T(db.last_req.status == 400);
          T(e.error == "query_parse_error");
      }

      try {
          db.view("test/no_reduce", {group_level: 1});
          T(0 == 1);
      } catch(e) {
          T(db.last_req.status == 400);
          T(e.error == "query_parse_error");
      }

      try {
        db.view("test/no_reduce", {reduce: true});
        T(0 == 1);
      } catch(e) {
        T(db.last_req.status == 400);
        T(e.error == "query_parse_error");
      }

      db.view("test/no_reduce", {reduce: false});
      TEquals(200, db.last_req.status, "reduce=false for map views (without"
                                     + " group or group_level) is allowed");

      try {
          db.view("test/with_reduce", {group: true, reduce: false});
          T(0 == 1);
      } catch(e) {
          T(db.last_req.status == 400);
          T(e.error == "query_parse_error");
      }

      try {
          db.view("test/with_reduce", {group_level: 1, reduce: false});
          T(0 == 1);
      } catch(e) {
        T(db.last_req.status == 400);
          T(e.error == "query_parse_error");
      }

      var designDoc3 = {
        _id:"_design/infinite",
        language: "javascript",
        views: {
          "infinite_loop" :{map:"function(doc) {while(true){};}"}
        }
      };
      T(db.save(designDoc3).ok);

      try {
          db.view("infinite/infinite_loop");
          T(0 == 1);
      } catch(e) {
          T(e.error == "os_process_error");
      }

      // Check error responses for invalid multi-get bodies.
      var path = "/" + db_name + "/_design/test/_view/no_reduce";
      var xhr = CouchDB.request("POST", path, {body: "[]"});
      T(xhr.status == 400);
      result = JSON.parse(xhr.responseText);
      T(result.error == "bad_request");
      T(result.reason == "Request body must be a JSON object");
      var data = "{\"keys\": 1}";
      xhr = CouchDB.request("POST", path, {body:data});
      T(xhr.status == 400);
      result = JSON.parse(xhr.responseText);
      T(result.error == "bad_request");
      T(result.reason == "`keys` member must be an array.");

      // if the reduce grows to fast, throw an overflow error
      var path = "/" + db_name + "/_design/testbig/_view/reduce_too_big";
      xhr = CouchDB.request("GET", path);
      T(xhr.status == 200);
      result = JSON.parse(xhr.responseText);
      T(result.rows[0].error == "reduce_overflow_error");

      try {
          db.query(function() {emit(null, null)}, null, {startkey: 2, endkey:1});
          T(0 == 1);
      } catch(e) {
          T(e.error == "query_parse_error");
          T(e.reason.match(/no rows can match/i));
      }

      // querying a temporary view should give "gone" error message
      var xhr = CouchDB.request("POST", "/" + db_name + "/_temp_view", {
        headers: {"Content-Type": "application/json"},
        body: JSON.stringify({language: "javascript",
          map : "function(doc){emit(doc.integer)}"
        })
      });
      T(xhr.status == 410);
      result = JSON.parse(xhr.responseText);
      T(result.error == "gone");
      T(result.reason == "Temporary views are not supported in CouchDB");
    // });

  // cleanup
  db.deleteDb();
};
