/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 _ from 'lodash';

import negate from 'lodash/negate';
import isNil from 'lodash/isNil';
import isEmpty from 'lodash/isEmpty';
import mixin from 'lodash/mixin';

const nonNil = negate(isNil);
const nonEmpty = negate(isEmpty);

mixin({
    nonNil,
    nonEmpty
});

export class EmptyBean {
    /**
     * @param {String} clsName
     */
    constructor(clsName) {
        this.properties = [];
        this.arguments = [];

        this.clsName = clsName;
    }

    isEmpty() {
        return false;
    }

    nonEmpty() {
        return !this.isEmpty();
    }

    isComplex() {
        return nonEmpty(this.properties) || !!_.find(this.arguments, (arg) => arg.clsName === 'MAP');
    }

    nonComplex() {
        return !this.isComplex();
    }

    findProperty(name) {
        return _.find(this.properties, {name});
    }
}

export class Bean extends EmptyBean {
    /**
     * @param {String} clsName
     * @param {String} id
     * @param {Object} src
     * @param {Object} dflts
     */
    constructor(clsName, id, src, dflts = {}) {
        super(clsName);

        this.id = id;

        this.src = src;
        this.dflts = dflts;
    }

    factoryMethod(name) {
        this.factoryMtd = name;

        return this;
    }

    /**
     * @param acc
     * @param clsName
     * @param model
     * @param name
     * @param {Function} nonEmpty Non empty function.
     * @param {Function} mapper Mapper function.
     * @returns {Bean}
     * @private
     */
    _property(acc, clsName, model, name, nonEmpty = () => true, mapper = (val) => val) {
        if (!this.src)
            return this;

        const value = mapper(_.get(this.src, model));

        if (nonEmpty(value) && value !== _.get(this.dflts, model))
            acc.push({clsName, name, value});

        return this;
    }

    isEmpty() {
        return isEmpty(this.arguments) && isEmpty(this.properties);
    }

    constructorArgument(clsName, value) {
        this.arguments.push({clsName, value});

        return this;
    }

    stringConstructorArgument(model) {
        return this._property(this.arguments, 'java.lang.String', model, null, nonEmpty);
    }

    intConstructorArgument(model) {
        return this._property(this.arguments, 'int', model, null, nonNil);
    }

    boolConstructorArgument(model) {
        return this._property(this.arguments, 'boolean', model, null, nonNil);
    }

    longConstructorArgument(model) {
        return this._property(this.arguments, 'long', model, null, nonNil);
    }

    classConstructorArgument(model) {
        return this._property(this.arguments, 'java.lang.Class', model, null, nonEmpty);
    }

    pathConstructorArgument(model) {
        return this._property(this.arguments, 'PATH', model, null, nonEmpty);
    }

    constantConstructorArgument(model) {
        if (!this.src)
            return this;

        const value = _.get(this.src, model);
        const dflt = _.get(this.dflts, model);

        if (nonNil(value) && nonNil(dflt) && value !== dflt.value)
            this.arguments.push({clsName: dflt.clsName, constant: true, value});

        return this;
    }

    propertyConstructorArgument(value, hint = '') {
        this.arguments.push({clsName: 'PROPERTY', value, hint});

        return this;
    }

    /**
     * @param {String} id
     * @param {EmptyBean|Bean} value
     * @returns {Bean}
     */
    beanConstructorArgument(id, value) {
        this.arguments.push({clsName: 'BEAN', id, value});

        return this;
    }

    /**
     * @param {String} id
     * @param {String} model
     * @param {Array.<Object>} entries
     * @returns {Bean}
     */
    mapConstructorArgument(id, model, entries) {
        if (!this.src)
            return this;

        const dflt = _.get(this.dflts, model);

        if (nonEmpty(entries) && nonNil(dflt) && entries !== dflt.entries) {
            this.arguments.push({
                clsName: 'MAP',
                id,
                keyClsName: dflt.keyClsName,
                keyField: dflt.keyField || 'name',
                valClsName: dflt.valClsName,
                valField: dflt.valField || 'value',
                entries
            });
        }

        return this;
    }

    valueOf(path) {
        return _.get(this.src, path) || _.get(this.dflts, path + '.value') || _.get(this.dflts, path);
    }

    includes(...paths) {
        return this.src && _.every(paths, (path) => {
            const value = _.get(this.src, path);
            const dflt = _.get(this.dflts, path);

            return nonNil(value) && value !== dflt;
        });
    }

    prop(clsName, name, value) {
        this.properties.push({clsName, name, value});
    }

    boolProperty(model, name = model) {
        return this._property(this.properties, 'boolean', model, name, nonNil);
    }

    byteProperty(model, name = model) {
        return this._property(this.properties, 'byte', model, name, nonNil);
    }

    intProperty(model, name = model) {
        return this._property(this.properties, 'int', model, name, nonNil);
    }

    longProperty(model, name = model) {
        return this._property(this.properties, 'long', model, name, nonNil);
    }

    floatProperty(model, name = model) {
        return this._property(this.properties, 'float', model, name, nonNil);
    }

    doubleProperty(model, name = model) {
        return this._property(this.properties, 'double', model, name, nonNil);
    }

    property(name, value, hint) {
        this.properties.push({clsName: 'PROPERTY', name, value, hint});

        return this;
    }

    propertyChar(name, value, hint) {
        this.properties.push({clsName: 'PROPERTY_CHAR', name, value, hint});

        return this;
    }

    propertyInt(name, value, hint) {
        this.properties.push({clsName: 'PROPERTY_INT', name, value, hint});

        return this;
    }

    stringProperty(model, name = model, mapper) {
        return this._property(this.properties, 'java.lang.String', model, name, nonEmpty, mapper);
    }

    pathProperty(model, name = model) {
        return this._property(this.properties, 'PATH', model, name, nonEmpty);
    }

    pathArrayProperty(id, name, items, varArg) {
        if (items && items.length)
            this.properties.push({clsName: 'PATH_ARRAY', id, name, items, varArg, typeClsName: 'PATH'});

        return this;
    }

    classProperty(model, name = model) {
        return this._property(this.properties, 'java.lang.Class', model, name, nonEmpty);
    }

    enumProperty(model, name = model) {
        if (!this.src)
            return this;

        const value = _.get(this.src, model);
        const dflt = _.get(this.dflts, model);

        if (nonNil(value) && nonNil(dflt) && value !== dflt.value)
            this.properties.push({clsName: dflt.clsName, name, value: dflt.mapper ? dflt.mapper(value) : value});

        return this;
    }

    emptyBeanProperty(model, name = model) {
        if (!this.src)
            return this;

        const cls = _.get(this.src, model);
        const dflt = _.get(this.dflts, model);

        if (nonEmpty(cls) && cls !== dflt)
            this.properties.push({clsName: 'BEAN', name, value: new EmptyBean(cls)});

        return this;
    }

    /**
     * @param {String} name
     * @param {EmptyBean|Bean} value
     * @returns {Bean}
     */
    beanProperty(name, value) {
        this.properties.push({clsName: 'BEAN', name, value});

        return this;
    }

    /**
     * @param {String} id
     * @param {String} name
     * @param {Array} items
     * @param {String} typeClsName
     * @returns {Bean}
     */
    arrayProperty(id, name, items, typeClsName = 'java.lang.String') {
        if (items && items.length)
            this.properties.push({clsName: 'ARRAY', id, name, items, typeClsName});

        return this;
    }

    /**
     * @param {String} id
     * @param {String} name
     * @param {Array} items
     * @param {String} typeClsName
     * @returns {Bean}
     */
    varArgProperty(id, name, items, typeClsName = 'java.lang.String') {
        if (items && items.length)
            this.properties.push({clsName: 'ARRAY', id, name, items, typeClsName, varArg: true});

        return this;
    }

    /**
     * @param {String} id
     * @param {String} name
     * @param {Array} items
     * @param {String} typeClsName
     * @param {String} implClsName
     * @returns {Bean}
     */
    collectionProperty(id, name, items, typeClsName = 'java.lang.String', implClsName = 'java.util.ArrayList') {
        if (items && items.length)
            this.properties.push({id, name, items, clsName: 'COLLECTION', typeClsName, implClsName});

        return this;
    }

    /**
     * @param {String} id
     * @param {String} model
     * @param {String} [name]
     * @param {Boolean} [ordered]
     * @returns {Bean}
     */
    mapProperty(id, model, name = model, ordered = false) {
        if (!this.src)
            return this;

        const entries = _.isString(model) ? _.get(this.src, model) : model;
        const dflt = _.isString(model) ? _.get(this.dflts, model) : _.get(this.dflts, name);

        if (nonEmpty(entries) && nonNil(dflt) && entries !== dflt.entries) {
            this.properties.push({
                clsName: 'MAP',
                id,
                name,
                ordered,
                keyClsName: dflt.keyClsName,
                keyField: dflt.keyField || 'name',
                valClsName: dflt.valClsName,
                valClsNameShow: dflt.valClsNameShow,
                valField: dflt.valField || 'value',
                entries,
                keyClsGenericType: dflt.keyClsGenericType,
                isKeyClsGenericTypeExtended: dflt.isKeyClsGenericTypeExtended
            });
        }

        return this;
    }

    propsProperty(id, model, name = model) {
        if (!this.src)
            return this;

        const entries = _.get(this.src, model);

        if (nonEmpty(entries))
            this.properties.push({clsName: 'java.util.Properties', id, name, entries});

        return this;
    }

    /**
     * @param {String} id
     * @param {String} name
     * @param {EmptyBean|Bean} value
     */
    dataSource(id, name, value) {
        if (value)
            this.properties.push({clsName: 'DATA_SOURCE', id, name, value});

        return this;
    }

    /**
     * @param {String} id
     * @param {String} name
     * @param {Array<String>} eventTypes
     */
    eventTypes(id, name, eventTypes) {
        this.properties.push({clsName: 'EVENT_TYPES', id, name, eventTypes});
    }
}
