'use strict';

var q = require("q");
var logger = require('../../../utils/Logger').loggers.get('db');
var SharedConstants = require('../../../../shared/constants/SharedConstants');
var cbConnection = require('./CouchbaseConnection');

/**
 * get offline documents based on the keys. The keys in documents will be matched against accessKeys on the account with a key name
 * of "Offline"
 * @param userId
 * @returns {*|promise}
 */
function getOfflineDocuments(accountId, startTime, countOnly, pageNumber, numberPerPage ) {
    var deferred = q.defer();

    var bucketName = cbConnection.getConfig().bucket;
    
    /* sync all documents where the user has a key with a right of offline. This is specified in the accessKeys element
     of the account Eg in the following documents with the keyId of the first entry under accessKeys would be synced because
     it has "Offline" in the rights:

     "accessKeys" : [
     {
     "keyId" : "7BC98642-529D-4423-94AD-5063CE262280",
     "rights" : [
     "Create",
     "Update",
     "Read",
     "Offline"
     ]
     },
     {
     "keyId" : "172CAD42-7E31-4A65-ACAE-82ABF8BB09E4",
     "rights" : [
     "Create",
     "Update",
     "Read"
     ]
     }
     */

    // create query to get offline documents
    var offlineQuery;

    // if there is no startTime all documents will be returned with the offline key, so we don't have to pass a query in
    if (startTime) {
        offlineQuery = 'SELECT `' + bucketName + '`.* FROM `' + bucketName + '` WHERE ' +
            'DATE_DIFF_STR(CLOCK_STR(), systemHeader.createdDate, "millisecond")' +
            ' AND systemHeader.versionId IS NOT NULL AND documentId IS NOT NULL ' +
            ' AND REGEXP_LIKE(documentId, "^[0-9a-zA-Z-]+$")';
    }

    var sortQuery = 'ORDER BY systemHeader.serverUpdatedDate ASC';
    var allVersions = false;

    // query for documents with the Offline key and no others
    var options = {
        alternativeKey: SharedConstants.OPERATION_TYPE_OFFLINE,
        excludeMissingKeys: true // exclude documents that don't have any keys, because we only want to cache documents that have
                                 // the offline key
    };

    DataService.findAll(offlineQuery,
        accountId,
        sortQuery,
        allVersions,
        options
    ).then(function successFunc(documents) {
        logger.info("Got documents to sync for offline use of count: " + documents.length);
        deferred.resolve(documents);
    }, function errorFunc(err) {
        logger.error("Error getting offline documents: " + err);
        deferred.reject(err);
    });

    return deferred.promise;
}

/**
 * get offline templates based on the keys
 * @param userId
 * @returns {*|promise}
 */
function getOfflineTemplates(accountId, templateIds) {
    var deferred = q.defer();

    var bucketName = cbConnection.getConfig().bucket;

    // create query to get offline documents
    var offlineQuery = 'SELECT `' + bucketName + '`.* FROM `' + bucketName + '` WHERE ' +
            'documentId IN $' + templateIds.length;

    var allVersions = false;

    // query for documents with the Offline key and no others
    var options = {
        alternativeKey: SharedConstants.OPERATION_TYPE_OFFLINE,
        excludeMissingKeys: true // exclude documents that don't have any keys, because we only want to cache documents that have
        // the offline key
    };

    DataService.findAll(offlineQuery,
        accountId,
        null,
        allVersions,
        options
    ).then(function successFunc(documents) {
            logger.info("Got documents to sync for offline use of count: " + documents.length);
            deferred.resolve(documents);
        }, function errorFunc(err) {
            logger.error("Error getting offline documents: " + err);
            deferred.reject(err);
        });

    return deferred.promise;
}

////////////////////////////////////
// public api
module.exports = {
    getOfflineDocuments: getOfflineDocuments,
    getOfflineTemplates: getOfflineTemplates
};
