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

define([
  'app',
  'api',
  'addons/databases/resources',
  'addons/documents/resources'
],

function (app, FauxtonAPI, Databases, Documents) {
  var Verifyinstall = FauxtonAPI.addon();

  var db = new Databases.Model({
    id: 'verifytestdb',
    name: 'verifytestdb'
  });

  var dbReplicate = new Databases.Model({
    id: 'verifytestdb_replicate',
    name: 'verifytestdb_replicate'
  });

  var doc, viewDoc;

  Verifyinstall.testProcess = {
    saveDoc: function () {
      doc = new Documents.Doc({_id: 'test_doc_1', a: 1}, {
        database: db
      });

      return doc.save();
    },

    destroyDoc: function () {
      return doc.destroy();
    },

    updateDoc: function () {
      doc.set({b: 'hello'});
      return doc.save();
    },

    saveDB: function () {
      return db.save();
    },

    setupDB: function (db) {
      var deferred = FauxtonAPI.Deferred();
      db.fetch()
      .then(function () {
        return db.destroy();
      }, function (xhr) {
        deferred.resolve();
      })
      .then(function () {
        deferred.resolve();
      }, function (xhr, error, reason) {
        if (reason === 'Unauthorized') {
          deferred.reject(xhr, error, reason);
        }
      });

      return deferred;
    },

    setup: function () {
      return FauxtonAPI.when([
        this.setupDB(db),
        this.setupDB(dbReplicate)
      ]);
    },

    testView: function () {
      var deferred = FauxtonAPI.Deferred();
      var promise = $.get(viewDoc.url() + '/_view/testview');

      promise.then(function (resp) {
        resp = _.isString(resp) ? JSON.parse(resp) : resp;
        var row = resp.rows[0];
        if (row.value === 6) {
          return deferred.resolve();
        }
        var reason = {
          reason: 'Values expect 6, got ' + row.value
        };

        deferred.reject({responseText: JSON.stringify(reason)});
      }, deferred.reject);

      return deferred;
    },

    setupView: function () {
      var doc1 = new Documents.Doc({_id: 'test_doc_10', a: 1}, { database: db });
      var doc2 = new Documents.Doc({_id: 'test_doc_20', a: 2}, { database: db });
      var doc3 = new Documents.Doc({_id: 'test_doc_30', a: 3}, { database: db });

      viewDoc = new Documents.Doc({
        _id: '_design/view_check',
        views: {
          'testview': {
            map: 'function (doc) { emit(doc._id, doc.a); }',
            reduce: '_sum'
          }
        }
      }, {
        database: db
      });

      return FauxtonAPI.when([doc1.save(), doc2.save(), doc3.save(), viewDoc.save()]);
    },

    setupReplicate: function () {
      return $.ajax({
        url: app.host + '/_replicate',
        contentType: 'application/json',
        type: 'POST',
        dataType: 'json',
        processData: false,
        data: JSON.stringify({
          create_target: true,
          source: 'verifytestdb',
          target: 'verifytestdb_replicate'
        })
      });
    },

    testReplicate: function () {
      var deferred = FauxtonAPI.Deferred();
      var promise = dbReplicate.fetch();

      promise.then(function () {
        var docCount = dbReplicate.get('doc_count');
        if ( docCount === 4) {
          deferred.resolve();
          return;
        }

        var reason = {
          reason: 'Replication Failed, expected 4 docs got ' + docCount
        };

        deferred.reject({responseText: JSON.stringify(reason)});
      }, deferred.reject);

      return deferred;
    },

    removeDBs: function () {
      dbReplicate.destroy();
      db.destroy();
    }
  };


  return Verifyinstall;
});
