/*!
 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
 *
 * 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.
 */

import * as ValidatorJS from 'validator';
import i18n from 'nfvo-utils/i18n/i18n.js';

class Validator {
    static get globalValidationFunctions() {
        return {
            required: value => {
                return typeof value === 'string'
                    ? value.replace(/\s+/g, '') !== ''
                    : value !== '';
            },
            requiredChooseOption: value => value !== '',
            maxLength: (value, length) =>
                ValidatorJS.isLength(value, { max: length }),
            minLength: (value, length) =>
                ValidatorJS.isLength(value, { min: length }),
            pattern: (value, pattern) => ValidatorJS.matches(value, pattern),
            numeric: value => {
                if (value === '') {
                    // to allow empty value which is not zero
                    return true;
                }
                return ValidatorJS.isNumeric(value);
            },
            maximum: (value, maxValue) => {
                return value === undefined ? true : value <= maxValue;
            },
            minimum: (value, minValue) => {
                return value === undefined ? true : value >= minValue;
            },
            maximumExclusive: (value, maxValue) => {
                return value === undefined ? true : value < maxValue;
            },
            minimumExclusive: (value, minValue) => {
                return value === undefined ? true : value > minValue;
            },
            alphanumeric: value => ValidatorJS.isAlphanumeric(value),
            alphanumericWithSpaces: value =>
                ValidatorJS.isAlphanumeric(value.replace(/ /g, '')),
            validateName: value =>
                ValidatorJS.isAlphanumeric(
                    value.replace(/\s|\.|\_|\-/g, ''),
                    'en-US'
                ),
            validateVendorName: value =>
                ValidatorJS.isAlphanumeric(
                    value.replace(/[\x7F-\xFF]|\s/g, ''),
                    'en-US'
                ),
            freeEnglishText: value =>
                ValidatorJS.isAlphanumeric(
                    value.replace(/\s|\.|\_|\-|\,|\(|\)|\?/g, ''),
                    'en-US'
                ),
            email: value => ValidatorJS.isEmail(value),
            ip: value => ValidatorJS.isIP(value),
            url: value => ValidatorJS.isURL(value),
            alphanumericWithUnderscores: value =>
                ValidatorJS.isAlphanumeric(value.replace(/_/g, '')),
            requiredChoiceWithOther: (value, otherValue) => {
                let chosen = value.choice;
                // if we have an empty multiple select we have a problem since it's required
                let validationFunc = this.globalValidationFunctions['required'];
                if (value.choices) {
                    if (value.choices.length === 0) {
                        return false;
                    } else {
                        // continuing validation with the first chosen value in case we have the 'Other' field
                        chosen = value.choices[0];
                    }
                }
                if (chosen !== otherValue) {
                    return validationFunc(chosen, true);
                } else {
                    // when 'Other' was chosen, validate other value
                    return validationFunc(value.other, true);
                }
            }
        };
    }

    static get globalValidationMessagingFunctions() {
        return {
            required: () => i18n('Field is required'),
            requiredChooseOption: () =>
                i18n('Field should have one of these options'),
            requiredChoiceWithOther: () => i18n('Field is required'),
            maxLength: (value, maxLength) =>
                i18n(
                    "Field value has exceeded it's limit, {maxLength}. current length: {length}",
                    {
                        length: value.length,
                        maxLength
                    }
                ),
            minLength: (value, minLength) =>
                i18n(
                    'Field value should contain at least {minLength} characters.',
                    {
                        minLength: minLength
                    }
                ),
            pattern: (value, pattern) =>
                i18n('Field value should match the pattern: {pattern}.', {
                    pattern: pattern
                }),
            numeric: () => i18n('Field value should contain numbers only.'),
            maximum: (value, maxValue) =>
                i18n('Field value should be less or equal to: {maxValue}.', {
                    maxValue: maxValue
                }),
            minimum: (value, minValue) =>
                i18n('Field value should be at least: {minValue}.', {
                    minValue: minValue.toString()
                }),
            maximumExclusive: (value, maxValue) =>
                i18n('Field value should be less than: {maxValue}.', {
                    maxValue: maxValue
                }),
            minimumExclusive: (value, minValue) =>
                i18n('Field value should be more than: {minValue}.', {
                    minValue: minValue.toString()
                }),
            alphanumeric: () =>
                i18n('Field value should contain letters or digits only.'),
            alphanumericWithSpaces: () =>
                i18n(
                    'Field value should contain letters, digits or spaces only.'
                ),
            validateName: () =>
                i18n(
                    'Field value should contain English letters, digits , spaces, underscores, dashes and dots only.'
                ),
            validateVendorName: () =>
                i18n(
                    'Field value should contain English letters digits and spaces only.'
                ),
            freeEnglishText: () =>
                i18n(
                    'Field value should contain  English letters, digits , spaces, underscores, dashes and dots only.'
                ),
            email: () => i18n('Field value should be a valid email address.'),
            ip: () => i18n('Field value should be a valid ip address.'),
            url: () => i18n('Field value should be a valid url address.'),
            general: () => i18n('Field value is invalid.'),
            alphanumericWithUnderscores: () =>
                i18n('Field value should contain letters, digits or _ only.')
        };
    }

    static validateItem(value, data, type) {
        let validationFunc = this.globalValidationFunctions[type];
        const isValid = validationFunc(value, data);
        let errorText = '';
        if (!isValid) {
            errorText = this.globalValidationMessagingFunctions[type](
                value,
                data
            );
        }
        return {
            isValid,
            errorText
        };
    }

    static validate(fieldName, value, validations, state, customValidations) {
        let result = { isValid: true, errorText: '' };
        for (let validation of validations) {
            result = this.validateItem(value, validation.data, validation.type);
            if (!result.isValid) {
                return result;
            }
        }
        if (customValidations) {
            let validationFunc = customValidations[fieldName];
            if (validationFunc) {
                result = validationFunc(value, state);
            }
        }
        return result;
    }

    static isItemNameAlreadyExistsInList({ itemId, itemName, list }) {
        itemName = itemName.toLowerCase();
        return list[itemName] && list[itemName] !== itemId;
    }
}

export default Validator;
