/* ====================================================================
   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 org.apache.poi.ss.formula.CacheAreaEval;
import org.apache.poi.ss.formula.eval.AreaEval;
import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.EvaluationException;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.OperandResolver;
import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.commons.math3.exception.DimensionMismatchException;
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
import org.apache.commons.math3.linear.LUDecomposition;
import org.apache.commons.math3.linear.MatrixUtils;

public abstract class MatrixFunction implements Function{

    public static void checkValues(double[] results) throws EvaluationException {
        for (double result : results) {
            if (Double.isNaN(result) || Double.isInfinite(result)) {
                throw new EvaluationException(ErrorEval.NUM_ERROR);
            }
        }
    }

    protected final double singleOperandEvaluate(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException {
        ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
        return OperandResolver.coerceValueToDouble(ve);
    }

    /* converts 1D array to 2D array for calculations */
    private static double[][] fillDoubleArray(double[] vector, int rows, int cols) throws EvaluationException {
        int i = 0, j = 0;

        if (rows < 1 || cols < 1 || vector.length < 1) {
            throw new EvaluationException(ErrorEval.VALUE_INVALID);
        }

        double[][] matrix = new double[rows][cols];

        for (double aVector : vector) {
            if (j < matrix.length) {
                if (i == matrix[0].length) {
                    i = 0;
                    j++;
                }
                if (j < matrix.length) matrix[j][i++] = aVector;
            }
        }

        return matrix;
    }

    /* retrieves 1D array from 2D array after calculations */
    private static double[] extractDoubleArray(double[][] matrix) throws EvaluationException {
        int idx = 0;

        if (matrix == null || matrix.length < 1 || matrix[0].length < 1) {
            throw new EvaluationException(ErrorEval.VALUE_INVALID);
        }

        double[] vector = new double[matrix.length * matrix[0].length];

        for (double[] aMatrix : matrix) {
            for (int i = 0; i < matrix[0].length; i++) {
                vector[idx++] = aMatrix[i];
            }
        }
        return vector;
    }

    public static abstract class OneArrayArg extends Fixed1ArgFunction {
        protected OneArrayArg() {
            //no fields to initialize
        }

        @Override
        public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
            if (arg0 instanceof AreaEval) {
                double[] result;
                double[][] resultArray;
                int width, height;

                try {
                    double[] values = collectValues(arg0);
                    double[][] array = fillDoubleArray(values, ((AreaEval) arg0).getHeight(), ((AreaEval) arg0).getWidth());
                    resultArray = evaluate(array);
                    width = resultArray[0].length;
                    height = resultArray.length;
                    result = extractDoubleArray(resultArray);

                    checkValues(result);
                }
                catch(EvaluationException e){
                    return e.getErrorEval();
                }

                ValueEval[] vals = new ValueEval[result.length];

                for (int idx = 0; idx < result.length; idx++) {
                    vals[idx] = new NumberEval(result[idx]);
                }

                if (result.length == 1) {
                    return vals[0];
                }
                else {
                    /* find a better solution */
                    return new CacheAreaEval(((AreaEval) arg0).getFirstRow(), ((AreaEval) arg0).getFirstColumn(),
                                            ((AreaEval) arg0).getFirstRow() + height - 1,
                                            ((AreaEval) arg0).getFirstColumn() + width - 1, vals);
                }
            }
            else {
                double[][] result;
                try {
                    double value = NumericFunction.singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
                    double[][] temp = {{value}};
                    result = evaluate(temp);
                    NumericFunction.checkValue(result[0][0]);
                }
                catch (EvaluationException e) {
                    return e.getErrorEval();
                }

                return new NumberEval(result[0][0]);
            }
        }

        protected abstract double[][] evaluate(double[][] d1) throws EvaluationException;
        protected abstract double[] collectValues(ValueEval arg) throws EvaluationException;
    }

    public static abstract class TwoArrayArg extends Fixed2ArgFunction {
        protected TwoArrayArg() {
            //no fields to initialize
        }

        @Override
        public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
            double[] result;
            int width, height;

            try {
                double[][] array0;
                double[][] array1;
                double[][] resultArray;

                if (arg0 instanceof AreaEval) {
                    try {
                        double[] values = collectValues(arg0);
                        array0 = fillDoubleArray(values, ((AreaEval) arg0).getHeight(), ((AreaEval) arg0).getWidth());
                    }
                    catch(EvaluationException e) {
                        return e.getErrorEval();
                    }
                }
                else {
                    try {
                        double value = NumericFunction.singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
                        array0 = new double[][] {{value}};
                    }
                    catch (EvaluationException e) {
                        return e.getErrorEval();
                    }
                }

                if (arg1 instanceof AreaEval) {
                   try {
                       double[] values = collectValues(arg1);
                      array1 = fillDoubleArray(values, ((AreaEval) arg1).getHeight(),((AreaEval) arg1).getWidth());
                   }
                   catch (EvaluationException e) {
                      return e.getErrorEval();
                   }
                }
                else {
                    try {
                        double value = NumericFunction.singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex);
                        array1 = new double[][] {{value}};
                    }
                    catch (EvaluationException e) {
                        return e.getErrorEval();
                    }
                }

                resultArray = evaluate(array0, array1);
                width = resultArray[0].length;
                height = resultArray.length;
                result = extractDoubleArray(resultArray);
                checkValues(result);
            }
            catch (EvaluationException e) {
                return e.getErrorEval();
            }
            catch (IllegalArgumentException e) {
                return ErrorEval.VALUE_INVALID;
            }


            ValueEval[] vals = new ValueEval[result.length];

            for (int idx = 0; idx < result.length; idx++) {
                vals[idx] = new NumberEval(result[idx]);
            }

            if (result.length == 1)
                return vals[0];
            else {
                return new CacheAreaEval(((AreaEval) arg0).getFirstRow(), ((AreaEval) arg0).getFirstColumn(),
                        ((AreaEval) arg0).getFirstRow() + height - 1,
                        ((AreaEval) arg0).getFirstColumn() + width - 1, vals);
            }

        }

        protected abstract double[][] evaluate(double[][] d1, double[][] d2) throws EvaluationException;
        protected abstract double[] collectValues(ValueEval arg) throws EvaluationException;

    }

    public static final class MutableValueCollector extends MultiOperandNumericFunction {
        public MutableValueCollector(boolean isReferenceBoolCounted, boolean isBlankCounted) {
            super(isReferenceBoolCounted, isBlankCounted);
        }
        public double[] collectValues(ValueEval...operands) throws EvaluationException {
            return getNumberArray(operands);
        }
        protected double evaluate(double[] values) {
            throw new IllegalStateException("should not be called");
        }
    }

    public static final Function MINVERSE = new OneArrayArg() {
        private final MutableValueCollector instance = new MutableValueCollector(false, false);

        protected double[] collectValues(ValueEval arg) throws EvaluationException {
            double[] values = instance.collectValues(arg);

            /* handle case where MDETERM is operating on an array that that is not completely filled*/
            if (arg instanceof AreaEval && values.length == 1)
                throw new EvaluationException(ErrorEval.VALUE_INVALID);

            return values;
        }

        protected double[][] evaluate(double[][] d1) throws EvaluationException {
            if (d1.length != d1[0].length) {
                throw new EvaluationException(ErrorEval.VALUE_INVALID);
            }

            Array2DRowRealMatrix temp = new Array2DRowRealMatrix(d1);
            return MatrixUtils.inverse(temp).getData();
        }
    };

    public static final Function TRANSPOSE = new OneArrayArg() {
        private final MutableValueCollector instance = new MutableValueCollector(false, true);

        protected double[] collectValues(ValueEval arg) throws EvaluationException {
            return instance.collectValues(arg);
        }

        protected double[][] evaluate(double[][] d1) throws EvaluationException {

            Array2DRowRealMatrix temp = new Array2DRowRealMatrix(d1);
            return temp.transpose().getData();
        }
    };

    public static final Function MDETERM = new Mdeterm();

    private static class Mdeterm extends OneArrayArg {
        private final MutableValueCollector instance;

        public Mdeterm() {
            instance = new MutableValueCollector(false, false);
            instance.setBlankEvalPolicy(MultiOperandNumericFunction.Policy.ERROR);
        }

        protected double[] collectValues(ValueEval arg) throws EvaluationException {
            double[] values = instance.collectValues(arg);

            /* handle case where MDETERM is operating on an array that that is not completely filled*/
            if (arg instanceof AreaEval && values.length == 1)
                throw new EvaluationException(ErrorEval.VALUE_INVALID);

            return instance.collectValues(arg);
        }

        protected double[][] evaluate(double[][] d1) throws EvaluationException {
            if (d1.length != d1[0].length) {
                throw new EvaluationException(ErrorEval.VALUE_INVALID);
            }

            double[][] result = new double[1][1];
            Array2DRowRealMatrix temp = new Array2DRowRealMatrix(d1);
            result[0][0] = (new LUDecomposition(temp)).getDeterminant();
            return result;
        }
    }

    public static final Function MMULT = new TwoArrayArg() {
        private final MutableValueCollector instance = new MutableValueCollector(false, false);

        protected double[] collectValues(ValueEval arg) throws EvaluationException {
            double[] values = instance.collectValues(arg);

            /* handle case where MMULT is operating on an array that is not completely filled*/
            if (arg instanceof AreaEval && values.length == 1)
                throw new EvaluationException(ErrorEval.VALUE_INVALID);

            return values;
        }

        protected double[][] evaluate(double[][] d1, double[][] d2) throws EvaluationException{
            Array2DRowRealMatrix first = new Array2DRowRealMatrix(d1);
            Array2DRowRealMatrix second = new Array2DRowRealMatrix(d2);

            try {
                MatrixUtils.checkMultiplicationCompatible(first, second);
            }
            catch (DimensionMismatchException e) {
                throw new EvaluationException(ErrorEval.VALUE_INVALID);
            }

            return first.multiply(second).getData();
        }
    };
}
