// 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.design_docs = function(debug) {
  var db_name = get_random_db_name();
  var db_name_a = get_random_db_name();
  var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
  var db2 = new CouchDB(db_name_a, {"X-Couch-Full-Commit":"false"});

  if (debug) debugger;

  db.createDb();
  db2.createDb();

/*
  var server_config = [
    {
      section: "query_server_config",
      key: "reduce_limit",
      value: "false"
    }
  ];
*/

  // var testFun = function() {
    var numDocs = 500;

    function makebigstring(power) {
      var str = "a";
      while(power-- > 0) {
        str = str + str;
      }
      return str;
    }

    var designDoc = {
      _id: "_design/test",
      language: "javascript",
      whatever : {
        stringzone : "exports.string = 'plankton';",
        commonjs : {
          whynot : "exports.test = require('../stringzone'); " +
            "exports.foo = require('whatever/stringzone');",
          upper : "exports.testing = require('./whynot').test.string.toUpperCase()+" +
            "module.id+require('./whynot').foo.string",
          circular_one: "require('./circular_two'); exports.name = 'One';",
          circular_two: "require('./circular_one'); exports.name = 'Two';"
        },
        // paths relative to parent
        idtest1: {
          a: {
            b: {d: "module.exports = require('../c/e').id;"},
            c: {e: "exports.id = module.id;"}
          }
        },
        // multiple paths relative to parent
        idtest2: {
          a: {
            b: {d: "module.exports = require('../../a/c/e').id;"},
            c: {e: "exports.id = module.id;"}
          }
        },
        // paths relative to module
        idtest3: {
          a: {
            b: "module.exports = require('./c/d').id;",
            c: {
              d: "module.exports = require('./e');",
              e: "exports.id = module.id;"
            }
          }
        },
        // paths relative to module and parent
        idtest4: {
          a: {
            b: "module.exports = require('../a/./c/d').id;",
            c: {
              d: "module.exports = require('./e');",
              e: "exports.id = module.id;"
            }
          }
        },
        // paths relative to root
        idtest5: {
          a: "module.exports = require('whatever/idtest5/b').id;",
          b: "exports.id = module.id;"
        }
      },
      views: {
        all_docs_twice: {
          map:
            (function(doc) {
              emit(doc.integer, null);
              emit(doc.integer, null);
            }).toString()
        },
        no_docs: {
          map:
            (function(doc) {
            }).toString()
        },
        single_doc: {
          map:
            (function(doc) {
              if (doc._id === "1") {
                emit(1, null);
              }
            }).toString()
        },
        summate: {
          map:
            (function(doc) {
              emit(doc.integer, doc.integer);
            }).toString(),
          reduce:
            (function(keys, values) {
              return sum(values);
            }).toString()
        },
        summate2: {
          map:
            (function(doc) {
              emit(doc.integer, doc.integer);
            }).toString(),
          reduce:
            (function(keys, values) {
              return sum(values);
            }).toString()
        },
        huge_src_and_results: {
          map:
            (function(doc) {
              if (doc._id === "1") {
                emit(makebigstring(16), null);
              }
            }).toString(),
          reduce:
            (function(keys, values) {
              return makebigstring(16);
            }).toString()
        },
        lib : {
          baz : "exports.baz = 'bam';",
          foo : {
            foo : "exports.foo = 'bar';",
            boom : "exports.boom = 'ok';",
            zoom : "exports.zoom = 'yeah';"
          }
        },
        commonjs : {
          map :
            (function(doc) {
              emit(null, require('views/lib/foo/boom').boom);
            }).toString()
        }
      },
      shows: {
        simple:
          (function() {
            return 'ok';
          }).toString(),
        requirey:
          (function() {
            var lib = require('whatever/commonjs/upper');
            return lib.testing;
          }).toString(),
        circular:
          (function() {
            var lib = require('whatever/commonjs/upper');
            return JSON.stringify(this);
          }).toString(),
        circular_require:
          (function() {
            return require('whatever/commonjs/circular_one').name;
          }).toString(),
        idtest1: (function() {
            return require('whatever/idtest1/a/b/d');
          }).toString(),
        idtest2: (function() {
            return require('whatever/idtest2/a/b/d');
          }).toString(),
        idtest3: (function() {
            return require('whatever/idtest3/a/b');
          }).toString(),
        idtest4: (function() {
            return require('whatever/idtest4/a/b');
          }).toString(),
        idtest5: (function() {
            return require('whatever/idtest5/a');
          }).toString()
      }
    }; // designDoc

    var xhr = CouchDB.request(
      "PUT", "/" + db_name_a + "/_design/test", {body: JSON.stringify(designDoc)}
    );
    var resp = JSON.parse(xhr.responseText);

    TEquals(resp.rev, db.save(designDoc).rev);

    // test commonjs require
    xhr = CouchDB.request("GET", "/" + db_name + "/_design/test/_show/requirey");
    T(xhr.status == 200);
    TEquals("PLANKTONwhatever/commonjs/upperplankton", xhr.responseText);

    xhr = CouchDB.request("GET", "/" + db_name + "/_design/test/_show/circular");
    T(xhr.status == 200);
    TEquals("javascript", JSON.parse(xhr.responseText).language);

    // test circular commonjs dependencies
    xhr = CouchDB.request(
      "GET",
      "/" + db_name + "/_design/test/_show/circular_require"
    );
    TEquals(200, xhr.status);
    TEquals("One", xhr.responseText);

    // test module id values are as expected:
    xhr = CouchDB.request("GET", "/" + db_name + "/_design/test/_show/idtest1");
    TEquals(200, xhr.status);
    TEquals("whatever/idtest1/a/c/e", xhr.responseText);

    xhr = CouchDB.request("GET", "/" + db_name + "/_design/test/_show/idtest2");
    TEquals(200, xhr.status);
    TEquals("whatever/idtest2/a/c/e", xhr.responseText);

    xhr = CouchDB.request("GET", "/" + db_name + "/_design/test/_show/idtest3");
    TEquals(200, xhr.status);
    TEquals("whatever/idtest3/a/c/e", xhr.responseText);

    xhr = CouchDB.request("GET", "/" + db_name + "/_design/test/_show/idtest4");
    TEquals(200, xhr.status);
    TEquals("whatever/idtest4/a/c/e", xhr.responseText);

    xhr = CouchDB.request("GET", "/" + db_name + "/_design/test/_show/idtest5");
    TEquals(200, xhr.status);
    TEquals("whatever/idtest5/b", xhr.responseText);


    var prev_view_sig = db.designInfo("_design/test").view_index.signature;
    var prev_view_size = db.designInfo("_design/test").view_index.disk_size;

    db.bulkSave(makeDocs(1, numDocs + 1));
    T(db.ensureFullCommit().ok);

    // test that we get correct design doc info back,
    // and also that GET /db/_design/test/_info
    // hasn't triggered an update of the views
    db.view("test/summate", {stale: "ok"}); // make sure view group's open
    for (var i = 0; i < 2; i++) {
      var dinfo = db.designInfo("_design/test");
      TEquals("test", dinfo.name);
      var vinfo = dinfo.view_index;
      TEquals(prev_view_size, vinfo.disk_size, "view group disk size didn't change");
      TEquals(false, vinfo.compact_running);
      TEquals(prev_view_sig, vinfo.signature, 'ddoc sig');
      // wait some time (there were issues where an update
      // of the views had been triggered in the background)
      var start = new Date().getTime();
      while (new Date().getTime() < start + 2000);
      TEquals(0, db.view("test/all_docs_twice", {stale: "ok"}).total_rows, 'view info');
      TEquals(0, db.view("test/single_doc", {stale: "ok"}).total_rows, 'view info');
      TEquals(0, db.view("test/summate", {stale: "ok"}).rows.length, 'view info');
      T(db.ensureFullCommit().ok);
      // restartServer();
    };

    db.bulkSave(makeDocs(numDocs + 1, numDocs * 2 + 1));
    T(db.ensureFullCommit().ok);

    // open view group
    db.view("test/summate", {stale: "ok"});
    // wait so the views can get initialized
    var start = new Date().getTime();
    while (new Date().getTime() < start + 2000);

    // test that POST /db/_view_cleanup
    // doesn't trigger an update of the views
    var len1 = db.view("test/all_docs_twice", {stale: "ok"}).total_rows;
    var len2 = db.view("test/single_doc", {stale: "ok"}).total_rows;
    var len3 = db.view("test/summate", {stale: "ok"}).rows.length;
    for (i = 0; i < 2; i++) {
      T(db.viewCleanup().ok);
      // wait some time (there were issues where an update
      // of the views had been triggered in the background)
      start = new Date().getTime();
      while (new Date().getTime() < start + 2000);
      TEquals(len1, db.view("test/all_docs_twice", {stale: "ok"}).total_rows, 'view cleanup');
      TEquals(len2, db.view("test/single_doc", {stale: "ok"}).total_rows, 'view cleanup');
      TEquals(len3, db.view("test/summate", {stale: "ok"}).rows.length, 'view cleanup');
      T(db.ensureFullCommit().ok);
      // restartServer();
      // we'll test whether the view group stays closed
      // and the views stay uninitialized (they should!)
      len1 = len2 = len3 = 0;
    };

    // test commonjs in map functions
    resp = db.view("test/commonjs", {limit:1});
    T(resp.rows[0].value == 'ok');

    // test that the _all_docs view returns correctly with keys
    var results = db.allDocs({startkey:"_design", endkey:"_design0"});
    T(results.rows.length == 1);

    for (i = 0; i < 2; i++) {
      var rows = db.view("test/all_docs_twice").rows;
      for (var j = 0; j < numDocs; j++) {
        T(rows[2 * j].key == (j + 1));
        T(rows[(2 * j) + 1].key == (j + 1));
      };
      T(db.view("test/no_docs").total_rows == 0);
      T(db.view("test/single_doc").total_rows == 1);
      T(db.ensureFullCommit().ok);
      // restartServer();
    };

    // test when language not specified, Javascript is implied
    var designDoc2 = {
      _id: "_design/test2",
      // language: "javascript",
      views: {
        single_doc: {
          map:
            (function(doc) {
              if (doc._id === "1") {
                emit(1, null);
              }
            }).toString()
        }
      }
    };

    T(db.save(designDoc2).ok);
    T(db.view("test2/single_doc").total_rows == 1);

    var summate = function(N) {
      return (N + 1) * (N / 2);
    };
    var result = db.view("test/summate");
    T(result.rows[0].value == summate(numDocs * 2));

    result = db.view("test/summate", {startkey: 4, endkey: 4});
    T(result.rows[0].value == 4);

    result = db.view("test/summate", {startkey: 4, endkey: 5});
    T(result.rows[0].value == 9);

    result = db.view("test/summate", {startkey: 4, endkey: 6});
    T(result.rows[0].value == 15);

    // test start_key and end_key aliases
    result = db.view("test/summate", {start_key: 4, end_key: 6});
    T(result.rows[0].value == 15);

    // Verify that a shared index (view def is an exact copy of "summate")
    // does not confuse the reduce stage
    result = db.view("test/summate2", {startkey: 4, endkey: 6});
    T(result.rows[0].value == 15);

    for(i = 1; i < (numDocs / 2); i += 30) {
      result = db.view("test/summate", {startkey: i, endkey: (numDocs - i)});
      T(result.rows[0].value == summate(numDocs - i) - summate(i - 1));
    }

    T(db.deleteDoc(designDoc).ok);
    waitForSuccess(function() {
      var ddoc = db.open(designDoc._id)
      if (ddoc != null) {
        throw({});
      }
      return true;
    }, 'db.open(designDoc._id)');
    T(db.view("test/no_docs") == null);

    T(db.ensureFullCommit().ok);
    // restartServer();
    T(db.open(designDoc._id) == null);
    T(db.view("test/no_docs") == null);

    // trigger ddoc cleanup
    T(db.viewCleanup().ok);
  //}; // enf of testFun

  // not used now as we don't have modifications so far (would have to put them in)
  //run_on_modified_server(server_config, testFun);

  // COUCHDB-1227 - if a design document is deleted, by adding a "_deleted"
  // field with the boolean value true, its validate_doc_update functions
  // should no longer have effect.
  db.deleteDb();
  // avoid Heisenbugs w/ files remaining - create a new name
  db_name = get_random_db_name();
  db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
  db.createDb();
  var ddoc = {
    _id: "_design/test",
    language: "javascript",
    validate_doc_update: (function(newDoc, oldDoc, userCtx, secObj) {
       if (newDoc.value % 2 == 0) {
          throw({forbidden: "dont like even numbers"});
       }
       return true;
    }).toString()
  };

  TEquals(true, db.save(ddoc).ok);
  try {
    db.save({_id: "doc1", value: 4});
    T(false, "doc insertion should have failed");
  } catch (x) {
    TEquals("forbidden", x.error);
  }

  var doc = db.open("doc1");
  TEquals(null, doc);
  ddoc._deleted = true;
  TEquals(true, db.save(ddoc).ok);

  try {
    TEquals(true, db.save({_id: "doc1", value: 4}).ok);
  } catch (x) {
    T(false, "doc insertion should have succeeded");
  }

  doc = db.open("doc1");
  TEquals(true, doc !== null, "doc was not persisted");
  TEquals(4, doc.value);

  // cleanup
  db.deleteDb();
  db2.deleteDb();
};
