/*******************************************************************************
 * 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.sling.scripting.sightly.impl.plugin;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.sling.scripting.sightly.compiler.RuntimeFunction;
import org.apache.sling.scripting.sightly.compiler.commands.Conditional;
import org.apache.sling.scripting.sightly.compiler.commands.Loop;
import org.apache.sling.scripting.sightly.compiler.commands.OutText;
import org.apache.sling.scripting.sightly.compiler.commands.OutputVariable;
import org.apache.sling.scripting.sightly.compiler.commands.VariableBinding;
import org.apache.sling.scripting.sightly.compiler.expression.Expression;
import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode;
import org.apache.sling.scripting.sightly.compiler.expression.MarkupContext;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperation;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperator;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.BooleanConstant;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.Identifier;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.MapLiteral;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.PropertyAccess;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.RuntimeCall;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.StringConstant;
import org.apache.sling.scripting.sightly.impl.compiler.Patterns;
import org.apache.sling.scripting.sightly.impl.compiler.PushStream;
import org.apache.sling.scripting.sightly.impl.compiler.Syntax;
import org.apache.sling.scripting.sightly.impl.compiler.frontend.CompilerContext;
import org.apache.sling.scripting.sightly.impl.filter.ExpressionContext;
import org.apache.sling.scripting.sightly.impl.html.MarkupUtils;

/**
 * Implementation for the attribute plugin.
 */
public class AttributePlugin extends AbstractPlugin {

    public AttributePlugin() {
        name = "attribute";
        priority = 150;
    }


    @Override
    public PluginInvoke invoke(Expression expression, PluginCallInfo callInfo, CompilerContext compilerContext) {
        String attributeName = decodeAttributeName(callInfo);
        if (attributeName != null && MarkupUtils.isSensitiveAttribute(attributeName)) {
            String warningMessage = String.format("Sensible attribute (%s) detected: event attributes (on*) and the style attribute " +
                    "cannot be generated with the data-sly-attribute block element; if you need to output a dynamic value for " +
                    "this attribute then use an expression with an appropriate context.", attributeName);
            compilerContext.getPushStream().warn(new PushStream.StreamMessage(warningMessage, expression.getRawText()));
            return new DefaultPluginInvoke(); //no-op invocation
        }
        return (attributeName != null)
                ? new SingleAttributeInvoke(attributeName, expression, compilerContext)
                : new MultiAttributeInvoke(expression.getRoot(), compilerContext);
    }

    private String decodeAttributeName(PluginCallInfo info) {
        String[] arguments = info.getArguments();
        if (arguments.length == 0) {
            return null;
        }
        return StringUtils.join(arguments, '-');
    }

    private final class SingleAttributeInvoke extends DefaultPluginInvoke {
        private final String attributeName;
        private final String isTrueValue;
        private final String escapedAttrValue;
        private final String shouldDisplayAttribute;

        private boolean writeAtEnd = true;
        private boolean beforeCall = true;
        private final String attrValue;
        private final ExpressionNode node;
        private final ExpressionNode contentNode;

        private SingleAttributeInvoke(String attributeName, Expression expression, CompilerContext compilerContext) {
            this.attributeName = attributeName;
            this.attrValue = compilerContext.generateVariable("attrValue_" + attributeName);
            this.escapedAttrValue = compilerContext.generateVariable("attrValueEscaped_" + attributeName);
            this.isTrueValue = compilerContext.generateVariable("isTrueValue_" + attributeName);
            this.shouldDisplayAttribute = compilerContext.generateVariable("shouldDisplayAttr_" + attributeName);
            this.node = expression.getRoot();
            if (!expression.containsOption(Syntax.CONTEXT_OPTION)) {
                this.contentNode = escapeNodeWithHint(compilerContext, new Identifier(attrValue), MarkupContext.ATTRIBUTE,
                        new StringConstant(attributeName));
            } else {
                this.contentNode = new Identifier(attrValue);
            }
        }

        @Override
        public void beforeAttribute(PushStream stream, String attributeName) {
            if (attributeName.equals(this.attributeName)) {
                if (beforeCall) {
                    emitStart(stream);
                }
                writeAtEnd = false;
            }
        }

        @Override
        public void beforeAttributeValue(PushStream stream, String attributeName, ExpressionNode attributeValue) {
            if (attributeName.equals(this.attributeName) && beforeCall) {
                emitWrite(stream);
                Patterns.beginStreamIgnore(stream);
            }
        }

        @Override
        public void afterAttributeValue(PushStream stream, String attributeName) {
            if (attributeName.equals(this.attributeName) && beforeCall) {
                Patterns.endStreamIgnore(stream);
            }
        }

        @Override
        public void afterAttribute(PushStream stream, String attributeName) {
            if (attributeName.equals(this.attributeName) && beforeCall) {
                emitEnd(stream);
            }
        }

        @Override
        public void afterAttributes(PushStream stream) {
            if (writeAtEnd) {
                emitStart(stream);
                stream.write(new OutText(" " + this.attributeName));
                emitWrite(stream);
                emitEnd(stream);
            }
        }

        @Override
        public void onPluginCall(PushStream stream, PluginCallInfo callInfo, Expression expression) {
            if ("attribute".equals(callInfo.getName())) {
                String attributeName = decodeAttributeName(callInfo);
                if (this.attributeName.equals(attributeName)) {
                    beforeCall = false;
                }
            }
        }

        private void emitStart(PushStream stream) {
            stream.write(new VariableBinding.Start(attrValue, node));
            stream.write(new VariableBinding.Start(escapedAttrValue, contentNode));
            stream.write(
                    new VariableBinding.Start(
                            shouldDisplayAttribute,
                            new BinaryOperation(
                                    BinaryOperator.OR,
                                    new Identifier(escapedAttrValue),
                                    new BinaryOperation(BinaryOperator.EQ, new StringConstant("false"), new Identifier(attrValue))
                            )
                    )
            );
            stream.write(new Conditional.Start(shouldDisplayAttribute, true));
        }

        private void emitWrite(PushStream stream) {
            stream.write(new VariableBinding.Start(isTrueValue,
                    new BinaryOperation(BinaryOperator.EQ,
                            new Identifier(attrValue),
                            BooleanConstant.TRUE)));
            stream.write(new Conditional.Start(isTrueValue, false));
            stream.write(new OutText("=\""));
            stream.write(new OutputVariable(escapedAttrValue));
            stream.write(new OutText("\""));
            stream.write(Conditional.END);
            stream.write(VariableBinding.END);
        }

        private void emitEnd(PushStream stream) {
            stream.write(Conditional.END);
            stream.write(VariableBinding.END);
            stream.write(VariableBinding.END);
            stream.write(VariableBinding.END);
        }
    }

    private final class MultiAttributeInvoke extends DefaultPluginInvoke {

        private final ExpressionNode attrMap;
        private final String attrMapVar;
        private final CompilerContext compilerContext;
        private boolean beforeCall = true;
        private final Set<String> ignored = new HashSet<>();

        private MultiAttributeInvoke(ExpressionNode attrMap, CompilerContext context) {
            this.attrMap = attrMap;
            this.compilerContext = context;
            this.attrMapVar = context.generateVariable("attrMap");
        }

        @Override
        public void beforeAttributes(PushStream stream) {
            stream.write(new VariableBinding.Start(attrMapVar, attrMap));
        }

        @Override
        public void beforeAttribute(PushStream stream, String attributeName) {
            ignored.add(attributeName);
            if (beforeCall) {
                String attrNameVar = compilerContext.generateVariable("attrName_" + attributeName);
                String attrValue = compilerContext.generateVariable("mapContains_" + attributeName);
                stream.write(new VariableBinding.Start(attrNameVar, new StringConstant(attributeName)));
                stream.write(new VariableBinding.Start(attrValue, attributeValueNode(new StringConstant(attributeName))));
                writeAttribute(stream, attrNameVar, attrValue);
                stream.write(new Conditional.Start(attrValue, false));
            }
        }

        @Override
        public void afterAttribute(PushStream stream, String attributeName) {
            if (beforeCall) {
                stream.write(Conditional.END);
                stream.write(VariableBinding.END);
                stream.write(VariableBinding.END);
            }
        }

        @Override
        public void onPluginCall(PushStream stream, PluginCallInfo callInfo, Expression expression) {
            if ("attribute".equals(callInfo.getName())) {
                String attrName = decodeAttributeName(callInfo);
                if (attrName == null) {
                    beforeCall = false;
                } else {
                    if (!beforeCall) {
                        ignored.add(attrName);
                    }
                }
            }
        }

        @Override
        public void afterAttributes(PushStream stream) {
            HashMap<String, ExpressionNode> ignoredLiteralMap = new HashMap<>();
            for (String attr : ignored) {
                ignoredLiteralMap.put(attr, new BooleanConstant(true));
            }
            MapLiteral ignoredLiteral = new MapLiteral(ignoredLiteralMap);
            String ignoredVar = compilerContext.generateVariable("ignoredAttributes");
            stream.write(new VariableBinding.Start(ignoredVar, ignoredLiteral));
            String attrNameVar = compilerContext.generateVariable("attrName");
            String attrNameEscaped = compilerContext.generateVariable("attrNameEscaped");
            String attrIndex = compilerContext.generateVariable("attrIndex");
            stream.write(new Loop.Start(attrMapVar, attrNameVar, attrIndex));
            stream.write(new VariableBinding.Start(attrNameEscaped,
                    escapeNode(new Identifier(attrNameVar), MarkupContext.ATTRIBUTE_NAME, null)));
            stream.write(new Conditional.Start(attrNameEscaped, true));
            String isIgnoredAttr = compilerContext.generateVariable("isIgnoredAttr");
            stream.write(
                    new VariableBinding.Start(isIgnoredAttr, new PropertyAccess(new Identifier(ignoredVar), new Identifier(attrNameVar))));
            stream.write(new Conditional.Start(isIgnoredAttr, false));
            String attrContent = compilerContext.generateVariable("attrContent");
            stream.write(new VariableBinding.Start(attrContent, attributeValueNode(new Identifier(attrNameVar))));
            writeAttribute(stream, attrNameEscaped, attrContent);
            stream.write(VariableBinding.END); //end of attrContent
            stream.write(Conditional.END);
            stream.write(VariableBinding.END);
            stream.write(Conditional.END);
            stream.write(VariableBinding.END);
            stream.write(Loop.END);
            stream.write(VariableBinding.END);
            stream.write(VariableBinding.END);
        }

        private void writeAttribute(PushStream stream, String attrNameVar, String attrContentVar) {
            String escapedContent = compilerContext.generateVariable("attrContentEscaped");
            String shouldDisplayAttribute = compilerContext.generateVariable("shouldDisplayAttr");
            stream.write(new VariableBinding.Start(escapedContent,
                    escapedExpression(new Identifier(attrContentVar), new Identifier(attrNameVar))));
            stream.write(
                    new VariableBinding.Start(
                            shouldDisplayAttribute,
                            new BinaryOperation(
                                    BinaryOperator.OR,
                                    new Identifier(escapedContent),
                                    new BinaryOperation(BinaryOperator.EQ, new StringConstant("false"), new Identifier(attrContentVar))
                            )
                    )
            );
            stream.write(new Conditional.Start(shouldDisplayAttribute, true));
            stream.write(new OutText(" "));   //write("attrName");
            writeAttributeName(stream, attrNameVar);
            writeAttributeValue(stream, escapedContent, attrContentVar);
            stream.write(Conditional.END);
            stream.write(VariableBinding.END);
            stream.write(VariableBinding.END);
        }

        private void writeAttributeName(PushStream stream, String attrNameVar) {
            stream.write(new OutputVariable(attrNameVar));
        }

        private void writeAttributeValue(PushStream stream, String escapedContent, String attrContentVar) {

            String isTrueVar = compilerContext.generateVariable("isTrueAttr"); // holds the comparison (attrValue == true)
            stream.write(new VariableBinding.Start(isTrueVar, //isTrueAttr = (attrContent == true)
                    new BinaryOperation(BinaryOperator.EQ, new Identifier(attrContentVar), BooleanConstant.TRUE)));
            stream.write(new Conditional.Start(isTrueVar, false)); //if (!isTrueAttr)
            stream.write(new OutText("=\""));

            stream.write(new OutputVariable(escapedContent)); //write(escapedContent)

            stream.write(new OutText("\""));
            stream.write(Conditional.END); //end if isTrueAttr
            stream.write(VariableBinding.END); //end scope for isTrueAttr
        }

        private ExpressionNode attributeValueNode(ExpressionNode attributeNameNode) {
            return new PropertyAccess(new Identifier(attrMapVar), attributeNameNode);
        }

        private ExpressionNode escapedExpression(ExpressionNode original, ExpressionNode hint) {
            return escapeNode(original, MarkupContext.ATTRIBUTE, hint);
        }

        private ExpressionNode escapeNode(ExpressionNode node, MarkupContext markupContext, ExpressionNode hint) {
            return escapeNodeWithHint(compilerContext, node, markupContext, hint);
        }
    }

    private static ExpressionNode escapeNodeWithHint(CompilerContext compilerContext, ExpressionNode node, MarkupContext markupContext,
                                                     ExpressionNode hint) {
        if (hint != null) {
            //todo: this is not the indicated way to escape via XSS. Correct after modifying the compiler context API
            return new RuntimeCall(RuntimeFunction.XSS, node, new StringConstant(markupContext.getName()), hint);
        }
        return compilerContext.adjustToContext(new Expression(node), markupContext, ExpressionContext.ATTRIBUTE).getRoot();
    }
}
