'use strict';

/**
 * @author schukai GmbH
 */

import {AbstractOperator} from "./abstractoperator.js";

/**
 * Constraints are used to define conditions that must be met by the value of a variable.
 *
 * The uniform API of the constraints allows chains to be formed.
 *
 * The OrOperator is used to link several constraints. The constraint is fulfilled if one of the constraints is fulfilled.
 *
 * ```
 * <script type="module">
 * import {OrOperator} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@latest/source/constraint/oroperator.js';
 * new OrOperator();
 * </script>
 * ```
 *
 * @example
 *
 * import {Valid} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@latest/source/constraints/valid.js';
 * import {Invalid} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@latest/source/constraints/invalid.js';
 * import {OrOperator} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@latest/source/constraints/oroperator.js';
 *
 * new OrOperator(
 * new Valid(), new Invalid()).isValid()
 * .then(()=>console.log(true))
 * .catch(()=>console.log(false));
 * // ↦ true
 *
 * new OrOperator(
 * new Invalid(), new Invalid()).isValid()
 * .then(()=>console.log(true))
 * .catch(()=>console.log(false));
 * // ↦ false
 *
 * @since 1.3.0
 * @copyright schukai GmbH
 * @memberOf Monster.Constraints
 * @summary A or operator 
 */
export class OrOperator extends AbstractOperator {

    /**
     * this method return a promise containing the result of the check.
     *
     * @param {*} value
     * @returns {Promise}
     */
    isValid(value) {
        var self = this;

        return new Promise(function (resolve, reject) {
            let a, b;

            self.operantA.isValid(value)
                .then(function () {
                    resolve();
                }).catch(function () {
                a = false;
                /** b has already been evaluated and was not true */
                if (b === false) {
                    reject();
                }
            });

            self.operantB.isValid(value)
                .then(function () {
                    resolve();
                }).catch(function () {
                b = false;
                /** b has already been evaluated and was not true */
                if (a === false) {
                    reject();
                }
            });
        });
    }


}