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

// Do some edit conflict detection tests
couchTests.elixir = true;
couchTests.conflicts = 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;

  // create a doc and save
  var doc = {_id:"foo",a:1,b:1};
  T(db.save(doc).ok);

  // reopen
  var doc2 = db.open(doc._id);

  // ensure the revisions are the same
  T(doc._id == doc2._id && doc._rev == doc2._rev);

  // edit the documents.
  doc.a = 2;
  doc2.a = 3;

  // save one document
  T(db.save(doc).ok);

  // save the other document
  try {
    db.save(doc2);  // this should generate a conflict exception
    T("no save conflict 1" && false); // we shouldn't hit here
  } catch (e) {
    T(e.error == "conflict");
  }

  var changes = db.changes();

  T(changes.results.length == 1);

  // Now clear out the _rev member and save. This indicates this document is
  // new, not based on an existing revision.
  doc2._rev = undefined;
  try {
    db.save(doc2); // this should generate a conflict exception
    T("no save conflict 2" && false); // we shouldn't hit here
  } catch (e) {
    T(e.error == "conflict");
  }

  // Make a few bad requests, specifying conflicting revs
  // ?rev doesn't match body
  var xhr = CouchDB.request("PUT", "/" + db_name + "/foo?rev=1-foobar", {
    body : JSON.stringify(doc)
  });
  T(xhr.status == 400);

  // If-Match doesn't match body
  xhr = CouchDB.request("PUT", "/" + db_name + "/foo", {
    headers: {"If-Match": "1-foobar"},
    body: JSON.stringify(doc)
  });
  T(xhr.status == 400);

  // ?rev= doesn't match If-Match
  xhr = CouchDB.request("PUT", "/" + db_name + "/foo?rev=1-boobaz", {
    headers: {"If-Match": "1-foobar"},
    body: JSON.stringify(doc2)
  });
  T(xhr.status == 400);

  // Now update the document using ?rev=
  xhr = CouchDB.request("PUT", "/" + db_name + "/foo?rev=" + doc._rev, {
    body: JSON.stringify(doc)
  });
  T(xhr.status == 201);

  // reopen
  var doc = db.open(doc._id);

  // Now delete the document from the database
  T(db.deleteDoc(doc).ok);

  T(db.save(doc2).ok);  // we can save a new document over a deletion without
                        // knowing the deletion rev.

  // Verify COUCHDB-1178
  var r1 = {"_id":"doc","foo":"bar"};
  var r2 = {"_id":"doc","foo":"baz","_rev":"1-4c6114c65e295552ab1019e2b046b10e"};
  var r3 = {"_id":"doc","foo":"bam","_rev":"2-cfcd6781f13994bde69a1c3320bfdadb"};
  var r4 = {"_id":"doc","foo":"bat","_rev":"3-cc2f3210d779aef595cd4738be0ef8ff"};

  T(db.save({"_id":"_design/couchdb-1178","validate_doc_update":"function(){}"}).ok);
  T(db.save(r1).ok);
  T(db.save(r2).ok);
  T(db.save(r3).ok);

  // we can't compact clustered DBs, but the tests will be meaningful still w/out
  //T(db.compact().ok);
  //while (db.info().compact_running) {};

  TEquals({"_id":"doc",
        "_rev":"3-cc2f3210d779aef595cd4738be0ef8ff",
        "foo":"bam",
        "_revisions":{"start":3,
          "ids":["cc2f3210d779aef595cd4738be0ef8ff",
                 "cfcd6781f13994bde69a1c3320bfdadb",
                                      "4c6114c65e295552ab1019e2b046b10e"]}},
    db.open("doc", {"revs": true}));
  TEquals([], db.bulkSave([r4, r3, r2], {"new_edits":false}), "no failures");

  db.deleteDb();
};
