/*
 * 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 freemarker.core;

import freemarker.template.TemplateException;

/**
 * A subclass of {@link TemplateException} that says that an FTL expression has evaluated to {@code null} or it refers
 * to something that doesn't exist. At least in FreeMarker 2.3.x these two cases aren't distinguished.
 */
public class InvalidReferenceException extends TemplateException {

    static final InvalidReferenceException FAST_INSTANCE;
    static {
        Environment prevEnv = Environment.getCurrentEnvironment();
        try {
            Environment.setCurrentEnvironment(null);
            FAST_INSTANCE = new InvalidReferenceException(
                    "Invalid reference. Details are unavailable, as this should have been handled by an FTL construct. "
                    + "If it wasn't, that's probably a bug in FreeMarker.",
                    null);
        } finally {
            Environment.setCurrentEnvironment(prevEnv);
        }
    }
    
    private static final Object[] TIP = {
        "If the failing expression is known to legally refer to something that's sometimes null or missing, "
        + "either specify a default value like myOptionalVar!myDefault, or use ",
        "<#if myOptionalVar??>", "when-present", "<#else>", "when-missing", "</#if>",
        ". (These only cover the last step of the expression; to cover the whole expression, "
        + "use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??"
    };

    private static final Object[] TIP_MISSING_ASSIGNMENT_TARGET = {
            "If the target variable is known to be legally null or missing sometimes, instead of something like ",
            "<#assign x += 1>", ", you could write ", "<#if x??>", "<#assign x += 1>", "</#if>",
            " or ", "<#assign x = (x!0) + 1>"
    };
    
    private static final String TIP_NO_DOLLAR =
            "Variable references must not start with \"$\", unless the \"$\" is really part of the variable name.";

    private static final String TIP_LAST_STEP_DOT =
            "It's the step after the last dot that caused this error, not those before it.";

    private static final String TIP_LAST_STEP_SQUARE_BRACKET =
            "It's the final [] step that caused this error, not those before it.";
    
    private static final String TIP_JSP_TAGLIBS =
            "The \"JspTaglibs\" variable isn't a core FreeMarker feature; "
            + "it's only available when templates are invoked through freemarker.ext.servlet.FreemarkerServlet"
            + " (or other custom FreeMarker-JSP integration solution).";
    
    /**
     * Creates and invalid reference exception that contains no information about what was missing or null.
     * As such, try to avoid this constructor.
     */
    public InvalidReferenceException(Environment env) {
        super("Invalid reference: The expression has evaluated to null or refers to something that doesn't exist.",
                env);
    }

    /**
     * Creates and invalid reference exception that contains no programmatically extractable information about the
     * blamed expression. As such, try to avoid this constructor, unless need to raise this expression from outside
     * the FreeMarker core.
     */
    public InvalidReferenceException(String description, Environment env) {
        super(description, env);
    }

    /**
     * This is the recommended constructor, but it's only used internally, and has no backward compatibility guarantees.
     * 
     * @param expression The expression that evaluates to missing or null. The last step of the expression should be
     *     the failing one, like in {@code goodStep.failingStep.furtherStep} it should only contain
     *     {@code goodStep.failingStep}.
     */
    InvalidReferenceException(_ErrorDescriptionBuilder description, Environment env, Expression expression) {
        super(null, env, expression, description);
    }

    /**
     * Use this whenever possible, as it returns {@link #FAST_INSTANCE} instead of creating a new instance, when
     * appropriate.
     */
    static InvalidReferenceException getInstance(Expression blamed, Environment env) {
        if (env != null && env.getFastInvalidReferenceExceptions()) {
            return FAST_INSTANCE;
        } else {
            if (blamed != null) {
                final _ErrorDescriptionBuilder errDescBuilder
                        = new _ErrorDescriptionBuilder("The following has evaluated to null or missing:").blame(blamed);
                if (endsWithDollarVariable(blamed)) {
                    errDescBuilder.tips(TIP_NO_DOLLAR, TIP);
                } else if (blamed instanceof Dot) {
                    final String rho = ((Dot) blamed).getRHO();
                    String nameFixTip = null;
                    if ("size".equals(rho)) {
                        nameFixTip = "To query the size of a collection or map use ?size, like myList?size";
                    } else if ("length".equals(rho)) {
                        nameFixTip = "To query the length of a string use ?length, like myString?size";
                    }
                    errDescBuilder.tips(
                            nameFixTip == null
                                    ? new Object[] { TIP_LAST_STEP_DOT, TIP }
                                    : new Object[] { TIP_LAST_STEP_DOT, nameFixTip, TIP });
                } else if (blamed instanceof DynamicKeyName) {
                    errDescBuilder.tips(TIP_LAST_STEP_SQUARE_BRACKET, TIP);
                } else if (blamed instanceof Identifier
                        && ((Identifier) blamed).getName().equals("JspTaglibs")) {
                    errDescBuilder.tips(TIP_JSP_TAGLIBS, TIP);
                } else {
                    errDescBuilder.tip(TIP);
                }
                return new InvalidReferenceException(errDescBuilder, env, blamed);
            } else {
                return new InvalidReferenceException(env);
            }
        }
    }
    
    /**
     * Used for assignments that use operators like {@code +=}, when the target variable was null/missing. 
     */
    static InvalidReferenceException getInstance(int scope, String missingAssignedVarName, String assignmentOperator,
            Environment env) {
        if (env != null && env.getFastInvalidReferenceExceptions()) {
            return FAST_INSTANCE;
        } else {
            final _ErrorDescriptionBuilder errDescBuilder = new _ErrorDescriptionBuilder(
                            "The target variable of the assignment, ",
                            new _DelayedJQuote(missingAssignedVarName),
                            ", was null or missing in the " + Assignment.scopeAsString(scope) + ", and the \"",
                            assignmentOperator, "\" operator must get its value from there before assigning to it."
                    );
            if (missingAssignedVarName.startsWith("$")) {
                errDescBuilder.tips(TIP_NO_DOLLAR, TIP_MISSING_ASSIGNMENT_TARGET);
            } else {
                errDescBuilder.tip(TIP_MISSING_ASSIGNMENT_TARGET);
            }
            return new InvalidReferenceException(errDescBuilder, env, null);
        }
    }

    private static boolean endsWithDollarVariable(Expression blame) {
        return blame instanceof Identifier && ((Identifier) blame).getName().startsWith("$")
                || blame instanceof Dot && ((Dot) blame).getRHO().startsWith("$");
    }
    
}
