/*
 * 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.struts2.components;

import com.opensymphony.xwork2.util.ValueStack;
import org.apache.commons.text.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.struts2.util.TextProviderHelper;
import org.apache.struts2.views.annotations.StrutsTag;
import org.apache.struts2.views.annotations.StrutsTagAttribute;

import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * <!-- START SNIPPET: javadoc -->
 * <p>
 * Render a I18n text message.
 * </p>
 *
 * <p>
 * The message must be in a resource bundle
 * with the same name as the action that it is associated with. In practice
 * this means that you should create a properties file in the same package
 * as your Java class with the same name as your class, but with .properties
 * extension.
 * </p>
 *
 * <p>
 * If the named message is not found in a property file, then the body of the
 * tag will be used as default message. If no value is found, the key of the
 * message will not be written out.
 * </p>
 * 
 * <p>
 * Note: If the <b>var</b> attribute is used with this tag, the tag's value will
 * <em>not</em> be written out.  Instead the result will be saved into the
 * action context (action scope).
 * </p>
 * <!-- END SNIPPET: javadoc -->
 *
 * <!-- START SNIPPET: params -->
 *
 * <ul>
 *      <li>name* (String) - the i18n message key</li>
 *      <li>escapeHtml (Boolean) - Escape HTML. Defaults to false</li>
 *      <li>escapeJavaScript (Boolean) - Escape JavaScript. Defaults to false</li>
 *      <li>escapeXml (Boolean) - Escape XML. Defaults to false</li>
 *      <li>escapeCsv (Boolean) - Escape CSV. Defaults to false</li>
 * </ul>
 *
 * <!-- END SNIPPET: params -->
 *
 * <p>
 * Example:
 * </p>
 *
 * <!-- START SNIPPET: exdescription -->
 * <p>Accessing messages from a given bundle (the i18n Shop example bundle in the first example) and using bundle defined through the framework in the second example.</p>
 * <!-- END SNIPPET: exdescription -->
 *
 * <pre>
 * <!-- START SNIPPET: example -->
 *
 * &lt;!-- First Example --&gt;
 * &lt;s:i18n name="struts.action.test.i18n.Shop"&gt;
 *     &lt;s:text name="main.title"/&gt;
 * &lt;/s:i18n&gt;
 *
 * &lt;!-- Second Example --&gt;
 * &lt;s:text name="main.title" /&gt;
 *
 * &lt;!-- Third Examlpe --&gt;
 * &lt;s:text name="i18n.label.greetings"&gt;
 *    &lt;s:param &gt;Mr Smith&lt;/s:param&gt;
 * &lt;/s:text&gt;
 *
 * <!-- END SNIPPET: example -->
 * </pre>
 *
 *
 * <pre>
 * <!-- START SNIPPET: i18nExample -->
 *
 * &lt;-- Fourth Example --&gt;
 * &lt;s:text name="some.key" /&gt;
 *
 * &lt;-- Fifth Example --&gt;
 * &lt;s:text name="some.invalid.key" &gt;
 *    The Default Message That Will Be Displayed
 * &lt;/s:text&gt;
 *
 * <!-- END SNIPPET: i18nExample -->
 * </pre>
 *
 * @see Param
 *
 */
@StrutsTag(
    name="text",
    tldTagClass="org.apache.struts2.views.jsp.TextTag",
    description="Render a I18n text message")
public class Text extends ContextBean implements Param.UnnamedParametric {

    private static final Logger LOG = LogManager.getLogger(Text.class);

    protected List<Object> values = Collections.emptyList();
    protected String actualName;
    protected String name;
    private boolean escapeHtml = false;
    private boolean escapeJavaScript = false;
    private boolean escapeXml = false;
    private boolean escapeCsv = false;

    public Text(ValueStack stack) {
        super(stack);
    }

    @StrutsTagAttribute(description = "Name of resource property to fetch", required = true)
    public void setName(String name) {
        this.name = name;
    }

    @StrutsTagAttribute(description="Whether to escape HTML", type="Boolean", defaultValue="false")
    public void setEscapeHtml(boolean escape) {
        this.escapeHtml = escape;
    }
    
    @StrutsTagAttribute(description="Whether to escape Javascript", type="Boolean", defaultValue="false")
    public void setEscapeJavaScript(boolean escapeJavaScript) {
        this.escapeJavaScript = escapeJavaScript;
    }

    @StrutsTagAttribute(description="Whether to escape XML", type="Boolean", defaultValue="false")
    public void setEscapeXml(boolean escapeXml) {
        this.escapeXml = escapeXml;
    }

    @StrutsTagAttribute(description="Whether to escape CSV (useful to escape a value for a column)", type="Boolean", defaultValue="false")
    public void setEscapeCsv(boolean escapeCsv) {
        this.escapeCsv = escapeCsv;
    }

    @Override
    public boolean usesBody() {
        // overriding this to true such that EVAL_BODY_BUFFERED is return and
        // bodyContent will be valid hence, text between start & end tag will
        // be honoured as default message (WW-1268)
        return true;
    }

    @Override
    public boolean end(Writer writer, String body) {
        actualName = findString(name, "name", "You must specify the i18n key. Example: welcome.header");
        String defaultMessage;
        if (StringUtils.isNotEmpty(body)) {
            defaultMessage = body;
        } else {
            defaultMessage = actualName;
        }

        String msg = TextProviderHelper.getText(actualName, defaultMessage, values, getStack());

        if (msg != null) {
            try {
                if (getVar() == null) {
                    writer.write(prepare(msg));
                } else {
                    putInContext(msg);
                }
            } catch (IOException e) {
                LOG.error("Could not write out Text tag", e);
            }
        }

        return super.end(writer, "");
    }

    @Override
    public void addParameter(String key, Object value) {
        addParameter(value);
    }

    @Override
    public void addParameter(Object value) {
        if (values.isEmpty()) {
            values = new ArrayList<>(4);
        }

        values.add(value);
    }

    private String prepare(String value) {
        String result = value;
        if (escapeHtml) {
            result = StringEscapeUtils.escapeHtml4(result);
        }
        if (escapeJavaScript) {
            result = StringEscapeUtils.escapeEcmaScript(result);
        }
        if (escapeXml) {
            result = StringEscapeUtils.escapeXml10(result);
        }
        if (escapeCsv) {
            result = StringEscapeUtils.escapeCsv(result);
        }

        return result;
    }
}
