/* ====================================================================
   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.FormulaParseException;
import org.apache.poi.ss.formula.FormulaParser;
import org.apache.poi.ss.formula.FormulaParsingWorkbook;
import org.apache.poi.ss.formula.OperationEvaluationContext;
import org.apache.poi.ss.formula.eval.BlankEval;
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.OperandResolver;
import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.poi.ss.formula.ptg.Area3DPxg;
import org.apache.poi.ss.usermodel.Table;

/**
 * Implementation for Excel function INDIRECT<p/>
 *
 * INDIRECT() returns the cell or area reference denoted by the text argument.<p/>
 *
 * <b>Syntax</b>:</br>
 * <b>INDIRECT</b>(<b>ref_text</b>,isA1Style)<p/>
 *
 * <b>ref_text</b> a string representation of the desired reference as it would
 * normally be written in a cell formula.<br/>
 * <b>isA1Style</b> (default TRUE) specifies whether the ref_text should be
 * interpreted as A1-style or R1C1-style.
 *
 * @author Josh Micich
 */
public final class Indirect implements FreeRefFunction {

    public static final FreeRefFunction instance = new Indirect();

    private Indirect() {
        // enforce singleton
    }

    public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
        if (args.length < 1) {
            return ErrorEval.VALUE_INVALID;
        }

        boolean isA1style;
        String text;
        try {
            ValueEval ve = OperandResolver.getSingleValue(args[0], ec.getRowIndex(), ec
                    .getColumnIndex());
            text = OperandResolver.coerceValueToString(ve);
            switch (args.length) {
                case 1:
                    isA1style = true;
                    break;
                case 2:
                    isA1style = evaluateBooleanArg(args[1], ec);
                    break;
                default:
                    return ErrorEval.VALUE_INVALID;
            }
        } catch (EvaluationException e) {
            return e.getErrorEval();
        }

        return evaluateIndirect(ec, text, isA1style);
    }

    private static boolean evaluateBooleanArg(ValueEval arg, OperationEvaluationContext ec)
            throws EvaluationException {
        ValueEval ve = OperandResolver.getSingleValue(arg, ec.getRowIndex(), ec.getColumnIndex());

        if (ve == BlankEval.instance || ve == MissingArgEval.instance) {
            return false;
        }
        // numeric quantities follow standard boolean conversion rules
        // for strings, only "TRUE" and "FALSE" (case insensitive) are valid
        return OperandResolver.coerceValueToBoolean(ve, false).booleanValue();
    }

    private static ValueEval evaluateIndirect(final OperationEvaluationContext ec, String text,
            boolean isA1style) {
        
        // Search backwards for '!' because sheet names can contain '!'
        int plingPos = text.lastIndexOf('!');

        String workbookName;
        String sheetName;
        String refText; // whitespace around this gets trimmed OK
        if (plingPos < 0) {
            workbookName = null;
            sheetName = null;
            refText = text;
        } else {
            String[] parts = parseWorkbookAndSheetName(text.subSequence(0, plingPos));
            if (parts == null) {
                return ErrorEval.REF_INVALID;
            }
            workbookName = parts[0];
            sheetName = parts[1];
            refText = text.substring(plingPos + 1);
        }

        if (Table.isStructuredReference.matcher(refText).matches()) {
            // The argument is structured reference
            Area3DPxg areaPtg = null;
            try {
                areaPtg = FormulaParser.parseStructuredReference(refText, (FormulaParsingWorkbook) ec.getWorkbook(), ec.getRowIndex());
            } catch (FormulaParseException e) {
                return ErrorEval.REF_INVALID;
            }
            return ec.getArea3DEval(areaPtg);
        } else {
            // The argument is regular reference
            String refStrPart1;
            String refStrPart2;
            int colonPos = refText.indexOf(':');
            if (colonPos < 0) {
                 refStrPart1 = refText.trim();
                 refStrPart2 = null;            
            } else {
                refStrPart1 = refText.substring(0, colonPos).trim();
                refStrPart2 = refText.substring(colonPos + 1).trim();
            }
            return ec.getDynamicReference(workbookName, sheetName, refStrPart1, refStrPart2, isA1style);
        }
    }

    /**
     * @return array of length 2: {workbookName, sheetName,}.  Second element will always be
     * present.  First element may be null if sheetName is unqualified.
     * Returns <code>null</code> if text cannot be parsed.
     */
    private static String[] parseWorkbookAndSheetName(CharSequence text) {
        int lastIx = text.length() - 1;
        if (lastIx < 0) {
            return null;
        }
        if (canTrim(text)) {
            return null;
        }
        char firstChar = text.charAt(0);
        if (Character.isWhitespace(firstChar)) {
            return null;
        }
        if (firstChar == '\'') {
            // workbookName or sheetName needs quoting
            // quotes go around both
            if (text.charAt(lastIx) != '\'') {
                return null;
            }
            firstChar = text.charAt(1);
            if (Character.isWhitespace(firstChar)) {
                return null;
            }
            String wbName;
            int sheetStartPos;
            if (firstChar == '[') {
                int rbPos = text.toString().lastIndexOf(']');
                if (rbPos < 0) {
                    return null;
                }
                wbName = unescapeString(text.subSequence(2, rbPos));
                if (wbName == null || canTrim(wbName)) {
                    return null;
                }
                sheetStartPos = rbPos + 1;
            } else {
                wbName = null;
                sheetStartPos = 1;
            }

            // else - just sheet name
            String sheetName = unescapeString(text.subSequence(sheetStartPos, lastIx));
            if (sheetName == null) { // note - when quoted, sheetName can
                                     // start/end with whitespace
                return null;
            }
            return new String[] { wbName, sheetName, };
        }

        if (firstChar == '[') {
            int rbPos = text.toString().lastIndexOf(']');
            if (rbPos < 0) {
                return null;
            }
            CharSequence wbName = text.subSequence(1, rbPos);
            if (canTrim(wbName)) {
                return null;
            }
            CharSequence sheetName = text.subSequence(rbPos + 1, text.length());
            if (canTrim(sheetName)) {
                return null;
            }
            return new String[] { wbName.toString(), sheetName.toString(), };
        }
        // else - just sheet name
        return new String[] { null, text.toString(), };
    }

    /**
     * @return <code>null</code> if there is a syntax error in any escape sequence
     * (the typical syntax error is a single quote character not followed by another).
     */
    private static String unescapeString(CharSequence text) {
        int len = text.length();
        StringBuilder sb = new StringBuilder(len);
        int i = 0;
        while (i < len) {
            char ch = text.charAt(i);
            if (ch == '\'') {
                // every quote must be followed by another
                i++;
                if (i >= len) {
                    return null;
                }
                ch = text.charAt(i);
                if (ch != '\'') {
                    return null;
                }
            }
            sb.append(ch);
            i++;
        }
        return sb.toString();
    }

    private static boolean canTrim(CharSequence text) {
        int lastIx = text.length() - 1;
        if (lastIx < 0) {
            return false;
        }
        if (Character.isWhitespace(text.charAt(0))) {
            return true;
        }
        if (Character.isWhitespace(text.charAt(lastIx))) {
            return true;
        }
        return false;
    }
}
