'use strict';

var documentUpdater = require('./DocumentUpdater');
var UtilDocumentId = require('./../utils/UtilDocumentId');
var UtilArray = require('../utils/UtilArray');

function resolveSimple(params) {

    var results = {};

    if (!params.newDocumentBaseDoc) {
        results.error = new Error("Base document not provided to ConflictResolver.resolveJSONPatch");
    } else if (!params.currentDocument) {
        results.error = new Error("Current Document object not provided to ConflictResolver.resolveJSONPatch");
    } else if (!params.newDocument) {
        results.error = new Error("New Document object not provided to ConflictResolver.resolveJSONPatch");
    }

    if (results.error) return results;

    //determine which version is older; let x be older, y newer
    var x = params.currentDocument;
    var y = params.newDocument;

    //evaluate which document is most recent.
    var currentDocCreateTime = new Date(params.currentDocument.systemHeader.createdDate).getTime();
    var newDocCreateTime = new Date(params.newDocument.systemHeader.createdDate).getTime();

    if(currentDocCreateTime > newDocCreateTime){
        var tmp = x;
        x = y;
        y = tmp;
    }

    documentUpdater.applyUpdatesSimple(params.newDocumentBaseDoc, x);
    documentUpdater.applyUpdatesSimple(params.newDocumentBaseDoc, y);

    var existedConflictData = params.newDocument.systemHeader.conflicts;
    var conflictVersions = existedConflictData ? existedConflictData.conflictingVersions : [];
    UtilArray.add(conflictVersions, params.newDocument.systemHeader.versionId, true);
    UtilArray.add(conflictVersions, params.currentDocument.systemHeader.versionId, true);
    params.newDocumentBaseDoc.systemHeader.conflicts = {
        resolved: false,
        conflictingVersions: conflictVersions
    };

    results.finalDoc = params.newDocumentBaseDoc;
    results.finalDoc.systemHeader.currentVersion = true;
    results.previousVersion = y;

    return results;
}

function resolveJSONPatch(params){

    var results = {};

    if (!params.newDocumentBaseDoc) {
        results.error = new Error("Base document not provided to ConflictResolver.resolveJSONPatch");
    } else if (!params.currentDocument) {
        results.error = new Error("Current Document object not provided to ConflictResolver.resolveJSONPatch");
    } else if (!params.newDocument) {
        results.error = new Error("New Document object not provided to ConflictResolver.resolveJSONPatch");
    }

    if (results.error) return results;

    //newDocument changes vs newDocumentBaseDoc
    //currentDocument changes vs newDocumentBaseDoc
    var newDocumentUpdates = params.newUpdates;
    var currentDocumentUpdates = params.oldUpdates;

    //determine which version is older; let x be older, y newer
    var x = currentDocumentUpdates;
    var y = newDocumentUpdates;
    var recent = params.newDocument;

    //evaluate which document is most recent.
    var currentDocCreateTime = new Date(params.currentDocument.systemHeader.createdDate).getTime();
    var newDocCreateTime = new Date(recent.systemHeader.createdDate).getTime();

    if(currentDocCreateTime > newDocCreateTime){
        x = newDocumentUpdates;
        y = currentDocumentUpdates;
        recent = params.currentDocument;
    }

    documentUpdater.applyUpdates(params.newDocumentBaseDoc, x);
    documentUpdater.applyUpdates(params.newDocumentBaseDoc, y);

    var existedConflictData = params.newDocument.systemHeader.conflicts;
    var conflictVersions = existedConflictData ? existedConflictData.conflictingVersions : [];
    UtilArray.add(conflictVersions, params.newDocument.systemHeader.versionId, true);
    UtilArray.add(conflictVersions, params.currentDocument.systemHeader.versionId, true);
    params.newDocumentBaseDoc.systemHeader.conflicts = {
        resolved: false,
        conflictingVersions: conflictVersions
    };

    results.finalDoc = params.newDocumentBaseDoc;
    results.finalDoc.systemHeader.currentVersion = true;
    results.previousVersion = recent;

    return results;
}

module.exports = {

    resolveSimple: resolveSimple,

    resolveJSONPatch: resolveJSONPatch
};