/* ====================================================================
   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.
==================================================================== */

package org.apache.poi.ss.formula.functions;

import java.util.Arrays;

import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.formula.ThreeDEval;
import org.apache.poi.ss.formula.TwoDEval;
import org.apache.poi.ss.formula.eval.BlankEval;
import org.apache.poi.ss.formula.eval.BoolEval;
import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.EvaluationException;
import org.apache.poi.ss.formula.eval.MissingArgEval;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.NumericValueEval;
import org.apache.poi.ss.formula.eval.OperandResolver;
import org.apache.poi.ss.formula.eval.RefEval;
import org.apache.poi.ss.formula.eval.StringValueEval;
import org.apache.poi.ss.formula.eval.ValueEval;

/**
 * This is the super class for all excel function evaluator
 * classes that take variable number of operands, and
 * where the order of operands does not matter
 */
public abstract class MultiOperandNumericFunction implements Function {
    public enum Policy {COERCE, SKIP, ERROR}

    private interface EvalConsumer<T, R> {
        void accept(T value, R receiver) throws EvaluationException;
    }

    private EvalConsumer<BoolEval, DoubleList> boolByRefConsumer;
    private EvalConsumer<BoolEval, DoubleList> boolByValueConsumer;
    private EvalConsumer<BlankEval, DoubleList> blankConsumer;
    private EvalConsumer<MissingArgEval, DoubleList> missingArgConsumer = ConsumerFactory.createForMissingArg(Policy.SKIP);

    protected MultiOperandNumericFunction(boolean isReferenceBoolCounted, boolean isBlankCounted) {
        boolByRefConsumer = ConsumerFactory.createForBoolEval(isReferenceBoolCounted ? Policy.COERCE : Policy.SKIP);
        boolByValueConsumer = ConsumerFactory.createForBoolEval(Policy.COERCE);
        blankConsumer = ConsumerFactory.createForBlank(isBlankCounted ? Policy.COERCE : Policy.SKIP);
    }

    static final double[] EMPTY_DOUBLE_ARRAY = {};

    private static class DoubleList {
        private double[] _array;
        private int _count;

        public DoubleList() {
            _array = new double[8];
            _count = 0;
        }

        public double[] toArray() {
            return _count < 1 ? EMPTY_DOUBLE_ARRAY : Arrays.copyOf(_array, _count);
        }

        private void ensureCapacity(int reqSize) {
            if (reqSize > _array.length) {
                int newSize = reqSize * 3 / 2; // grow with 50% extra
                _array = Arrays.copyOf(_array, newSize);
            }
        }

        public void add(double value) {
            ensureCapacity(_count + 1);
            _array[_count] = value;
            _count++;
        }
    }

    private static final int DEFAULT_MAX_NUM_OPERANDS = SpreadsheetVersion.EXCEL2007.getMaxFunctionArgs();

    public void setMissingArgPolicy(Policy policy) {
        missingArgConsumer = ConsumerFactory.createForMissingArg(policy);
    }

    public void setBlankEvalPolicy(Policy policy) {
        blankConsumer = ConsumerFactory.createForBlank(policy);
    }

    public final ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
        try {
            double[] values = getNumberArray(args);
            double d = evaluate(values);
            if (Double.isNaN(d) || Double.isInfinite(d)) {
                return ErrorEval.NUM_ERROR;
            }
            return new NumberEval(d);
        } catch (EvaluationException e) {
            return e.getErrorEval();
        }
    }

    protected abstract double evaluate(double[] values) throws EvaluationException;

    /**
     * Maximum number of operands accepted by this function.
     * Subclasses may override to change default value.
     */
    protected int getMaxNumOperands() {
        return DEFAULT_MAX_NUM_OPERANDS;
    }

    /**
     * Returns a double array that contains values for the numeric cells
     * from among the list of operands. Blanks and Blank equivalent cells
     * are ignored. Error operands or cells containing operands of type
     * that are considered invalid and would result in #VALUE! error in
     * excel cause this function to return <code>null</code>.
     *
     * @return never <code>null</code>
     */
    protected final double[] getNumberArray(ValueEval[] operands) throws EvaluationException {
        if (operands.length > getMaxNumOperands()) {
            throw EvaluationException.invalidValue();
        }
        DoubleList retval = new DoubleList();

        for (int i = 0, iSize = operands.length; i < iSize; i++) {
            collectValues(operands[i], retval);
        }
        return retval.toArray();
    }

    /**
     * Whether to count nested subtotals.
     */
    public boolean isSubtotalCounted() {
        return true;
    }

    /**
     * @return true if values in hidden rows are counted
     * @see Subtotal
     */
    public boolean isHiddenRowCounted() {
        return true;
    }

    /**
     * Collects values from a single argument
     */
    private void collectValues(ValueEval operand, DoubleList temp) throws EvaluationException {
        if (operand instanceof ThreeDEval) {
            ThreeDEval ae = (ThreeDEval) operand;
            for (int sIx = ae.getFirstSheetIndex(); sIx <= ae.getLastSheetIndex(); sIx++) {
                int width = ae.getWidth();
                int height = ae.getHeight();
                for (int rrIx = 0; rrIx < height; rrIx++) {
                    for (int rcIx = 0; rcIx < width; rcIx++) {
                        ValueEval ve = ae.getValue(sIx, rrIx, rcIx);
                        if (!isSubtotalCounted() && ae.isSubTotal(rrIx, rcIx)) continue;
                        if (!isHiddenRowCounted() && ae.isRowHidden(rrIx)) continue;
                        collectValue(ve, true, temp);
                    }
                }
            }
            return;
        }
        if (operand instanceof TwoDEval) {
            TwoDEval ae = (TwoDEval) operand;
            int width = ae.getWidth();
            int height = ae.getHeight();
            for (int rrIx = 0; rrIx < height; rrIx++) {
                for (int rcIx = 0; rcIx < width; rcIx++) {
                    ValueEval ve = ae.getValue(rrIx, rcIx);
                    if (!isSubtotalCounted() && ae.isSubTotal(rrIx, rcIx)) continue;
                    collectValue(ve, true, temp);
                }
            }
            return;
        }
        if (operand instanceof RefEval) {
            RefEval re = (RefEval) operand;
            for (int sIx = re.getFirstSheetIndex(); sIx <= re.getLastSheetIndex(); sIx++) {
                collectValue(re.getInnerValueEval(sIx), true, temp);
            }
            return;
        }
        collectValue(operand, false, temp);
    }

    private void collectValue(ValueEval ve, boolean isViaReference, DoubleList temp) throws EvaluationException {
        if (ve == null) {
            throw new IllegalArgumentException("ve must not be null");
        }
        if (ve instanceof BoolEval) {
            BoolEval boolEval = (BoolEval) ve;
            if (isViaReference) {
                boolByRefConsumer.accept(boolEval, temp);
            } else {
                boolByValueConsumer.accept(boolEval, temp);
            }
            return;
        }
        if (ve instanceof NumericValueEval) {
            NumericValueEval ne = (NumericValueEval) ve;
            temp.add(ne.getNumberValue());
            return;
        }
        if (ve instanceof StringValueEval) {
            if (isViaReference) {
                // ignore all ref strings
                return;
            }
            String s = ((StringValueEval) ve).getStringValue();
            Double d = OperandResolver.parseDouble(s);
            if (d == null) {
                throw new EvaluationException(ErrorEval.VALUE_INVALID);
            }
            temp.add(d.doubleValue());
            return;
        }
        if (ve instanceof ErrorEval) {
            throw new EvaluationException((ErrorEval) ve);
        }
        if (ve == BlankEval.instance) {
            blankConsumer.accept((BlankEval) ve, temp);
            return;
        }
        if (ve == MissingArgEval.instance) {
            missingArgConsumer.accept((MissingArgEval) ve, temp);
            return;
        }
        throw new RuntimeException("Invalid ValueEval type passed for conversion: ("
                + ve.getClass() + ")");
    }

    private static class ConsumerFactory {
        static EvalConsumer<MissingArgEval, DoubleList> createForMissingArg(Policy policy) {
            final EvalConsumer<MissingArgEval, DoubleList> coercer =
                    (MissingArgEval value, DoubleList receiver) -> receiver.add(0.0);
            return createAny(coercer, policy);
        }

        static EvalConsumer<BoolEval, DoubleList> createForBoolEval(Policy policy) {
            final EvalConsumer<BoolEval, DoubleList> coercer =
                    (BoolEval value, DoubleList receiver) -> receiver.add(value.getNumberValue());
            return createAny(coercer, policy);
        }

        static EvalConsumer<BlankEval, DoubleList> createForBlank(Policy policy) {
            final EvalConsumer<BlankEval, DoubleList> coercer =
                    (BlankEval value, DoubleList receiver) -> receiver.add(0.0);
            return createAny(coercer, policy);
        }

        private static <T> EvalConsumer<T, DoubleList> createAny(EvalConsumer<T, DoubleList> coercer, Policy policy) {
            switch (policy) {
                case COERCE:
                    return coercer;
                case SKIP:
                    return doNothing();
                case ERROR:
                    return throwValueInvalid();
                default:
                    throw new AssertionError();
            }
        }

        private static <T> EvalConsumer<T, DoubleList> doNothing() {
            return (T value, DoubleList receiver) -> {
            };
        }

        private static <T> EvalConsumer<T, DoubleList> throwValueInvalid() {
            return (T value, DoubleList receiver) -> {
                throw new EvaluationException(ErrorEval.VALUE_INVALID);
            };
        }
    }
}
