'use strict';
var logger = require('../utils/Logger').loggers.get('db');
var SharedConstants = require('../../shared/constants/SharedConstants');
var UtilDate = require('../utils/UtilDate');

var q = require("q");
var lodashString = require('lodash/string');

exports.templateValidatorAndMapping = function (document, template, userId, operation) {
    var deferred = q.defer();

    //check the createdDate if its specified and is valid
    if (document && document.systemHeader && document.systemHeader.createdDate) {
        if (UtilDate.convertToDate(document.systemHeader.createdDate)) {
            deferred.resolve();
        } else {
            deferred.reject("Invalid date value in systemHeader.createdDate");
        }
    } else {
        deferred.resolve();
    }

    return deferred.promise;
};

exports.validate = function (template) {

    var result = {};

    if (template) {
        var components = template.components;
        result = validateComponents(components);
        return result;
    } else {
        result.res = false;
        result.msg = 'Invalid template!';
        return result;
    }
};

function isComponentNotRequireName(component){
    var retVal = false;

    if (component.hasOwnProperty('type') && component['type']){
        var componentType = component['type'];
        if (componentType === SharedConstants.FIELD_TYPE_HTML){
            retVal = true;
        }
    }

    return retVal;
}

function validateComponents(components) {

    var result = {};
    result.res = true;
    result.msg = 'Template is OK!';

    logger.info('Validating template components using template validator....');

    if (components) {
            for (var i = 0, len = components.length; i < len; i++) {
            var components = components[i];
            var lstKeys = [];
            for (var key in component) {
                lstKeys.push(key);
                var firstChar = key.charAt(0);

                //Check key for name, componentName, type
                if (!component.hasOwnProperty('type') && lodashString.startsWith(component['componentName'], "ft-")) {
                    result.res = false;
                    result.msg = 'Component ' + (component.name || "") + ' at position ' + i + ' does not have type';
                    break;
                } else if (!component['type'] && lodashString.startsWith(component['componentName'], "ft-")) {
                    result.res = false;
                    result.msg = 'Component ' + (component.name || "") + ' at position ' + i
                        + ' does not have value for type';
                    break;
                }
                else if (!isComponentNotRequireName(component) && !component.hasOwnProperty('name')) {
                    result.res = false;
                    result.msg = 'Component at position ' + i + ' does not have name property or is not camel case';
                    break;
                } else if (!isComponentNotRequireName(component) && !component['name']) {
                    result.res = false;
                    result.msg = 'Component at position ' + i + ' does not have value for name';
                    break;

                } else if (!component.hasOwnProperty('componentName')) {
                    result.res = false;
                    result.msg = 'Component ' + component.name + ' at position ' + i +
                        ' does not have componentName or is not camel case';
                    break;
                } else if (!component['componentName']) {
                    result.res = false;
                    result.msg = 'Component ' + component.name + ' at position ' + i
                        + ' does not have value for componentName';
                    break;
                } else if ((firstChar !== firstChar.toLowerCase() && firstChar === firstChar.toUpperCase()) ||
                    key.indexOf(" ") > -1 || key.toString().indexOf("_") > -1) {
                    //Check Name start with lower case and in a camel case
                    result.res = false;
                    result.msg = 'Property ' + key + ' of the component ' + component.name + ' at position ' + i
                        + ' is not camel case';
                    break;
                }
            }

            for (var k = 0, l1 = lstKeys.length; k < l1 - 1; k++) {
                for (var j = 1, l2 = lstKeys.length; j < l2; j++) {
                    if (lstKeys[k] === lstKeys[j]) {
                        result.res = false;
                        result.msg = 'Found duplicate component name - ' + lstKeys[j];
                        break;
                    }
                }
                break;
            }
        }
        return result;
    } else {
        result.res = false;
        result.msg = 'No component found!';
        return result;
    }
}
