/**
 * Copyright (C) 2012 Google Inc.
 * Licensed to The Android Open Source Project.
 *
 * Licensed 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 com.android.mail.ui;

import android.content.Context;

import com.android.mail.R;
import com.android.mail.utils.LogTag;
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.Utils;
import com.google.common.annotations.VisibleForTesting;

import java.util.regex.Pattern;

/**
 * Renders data into very simple string-substitution HTML templates for conversation view.
 */
public class HtmlConversationTemplates extends AbstractHtmlTemplates {

    /**
     * Prefix applied to a message id for use as a div id
     */
    public static final String MESSAGE_PREFIX = "m";

    private static final String TAG = LogTag.getLogTag();

    /**
     * Pattern for HTML img tags with a "src" attribute where the value is an absolutely-specified
     * HTTP or HTTPS URL. In other words, these are images with valid URLs that we should munge to
     * prevent WebView from firing bad onload handlers for them. Part of the workaround for
     * b/5522414.
     *
     * Pattern documentation:
     * There are 3 top-level parts of the pattern:
     * 1. required preceding string
     * 2. the literal string "src"
     * 3. required trailing string
     *
     * The preceding string must be an img tag "<img " with intermediate spaces allowed. The
     * trailing whitespace is required.
     * Non-whitespace chars are allowed before "src", but if they are present, they must be followed
     * by another whitespace char. The idea is to allow other attributes, and avoid matching on
     * "src" in a later attribute value as much as possible.
     *
     * The following string must contain "=" and "http", with intermediate whitespace and single-
     * and double-quote allowed in between. The idea is to avoid matching Gmail-hosted relative URLs
     * for inline attachment images of the form "?view=KEYVALUES".
     *
     */
    private static final Pattern sAbsoluteImgUrlPattern = Pattern.compile(
            "(<\\s*img\\s+(?:[^>]*\\s+)?)src(\\s*=[\\s'\"]*http)", Pattern.CASE_INSENSITIVE
                    | Pattern.MULTILINE);
    /**
     * The text replacement for {@link #sAbsoluteImgUrlPattern}. The "src" attribute is set to
     * something inert and not left unset to minimize interactions with existing JS.
     */
    private static final String IMG_URL_REPLACEMENT = "$1src='data:' blocked-src$2";

    private static boolean sLoadedTemplates;
    private static String sSuperCollapsed;
    private static String sBorder;
    private static String sMessage;
    private static String sConversationUpper;
    private static String sConversationLower;

    public HtmlConversationTemplates(Context context) {
        super(context);

        // The templates are small (~2KB total in ICS MR2), so it's okay to load them once and keep
        // them in memory.
        if (!sLoadedTemplates) {
            sLoadedTemplates = true;
            sSuperCollapsed = readTemplate(R.raw.template_super_collapsed);
            sBorder = readTemplate(R.raw.template_border);
            sMessage = readTemplate(R.raw.template_message);
            sConversationUpper = readTemplate(R.raw.template_conversation_upper);
            sConversationLower = readTemplate(R.raw.template_conversation_lower);
        }
    }

    public void appendSuperCollapsedHtml(int firstCollapsed, int blockHeight) {
        if (!mInProgress) {
            throw new IllegalStateException("must call startConversation first");
        }

        append(sSuperCollapsed, firstCollapsed, blockHeight);
    }

    /**
     * Adds a spacer for the border that vertically separates cards.
     * @param blockHeight height of the border
     */
    public void appendBorder(int blockHeight) {
        append(sBorder, blockHeight);
    }

    @VisibleForTesting
    static String replaceAbsoluteImgUrls(final String html) {
        return sAbsoluteImgUrlPattern.matcher(html).replaceAll(IMG_URL_REPLACEMENT);
    }

    public void appendMessageHtml(HtmlMessage message, boolean isExpanded,
            boolean safeForImages, int headerHeight, int footerHeight) {

        final String bodyDisplay = isExpanded ? "block" : "none";
        final String expandedClass = isExpanded ? "expanded" : "";
        final String showImagesClass = safeForImages ? "mail-show-images" : "";

        String body = message.getBodyAsHtml();

        /* Work around a WebView bug (5522414) in setBlockNetworkImage that causes img onload event
         * handlers to fire before an image is loaded.
         * WebView will report bad dimensions when revealing inline images with absolute URLs, but
         * we can prevent WebView from ever seeing those images by changing all img "src" attributes
         * into "gm-src" before loading the HTML. Parsing the potentially dirty HTML input is
         * prohibitively expensive with TagSoup, so use a little regular expression instead.
         *
         * To limit the scope of this workaround, only use it on messages that the server claims to
         * have external resources, and even then, only use it on img tags where the src is absolute
         * (i.e. url does not begin with "?"). The existing JavaScript implementation of this
         * attribute swap will continue to handle inline image attachments (they have relative
         * URLs) and any false negatives that the regex misses. This maintains overall security
         * level by not relying solely on the regex.
         */
        if (!safeForImages && message.embedsExternalResources()) {
            body = replaceAbsoluteImgUrls(body);
        }

        append(sMessage,
                getMessageDomId(message),
                expandedClass,
                headerHeight,
                showImagesClass,
                bodyDisplay,
                body,
                bodyDisplay,
                footerHeight
        );
    }

    public String getMessageDomId(HtmlMessage msg) {
        return MESSAGE_PREFIX + msg.getId();
    }

    public void startConversation(int sideMargin, int conversationHeaderHeight) {
        if (mInProgress) {
            throw new IllegalStateException(
                    "Should not call start conversation until end conversation has been called");
        }

        reset();
        final String border = Utils.isRunningKitkatOrLater() ?
                "img[blocked-src] { border: 1px solid #CCCCCC; }" : "";
        append(sConversationUpper, border,  sideMargin, conversationHeaderHeight);
        mInProgress = true;
    }

    public String endConversation(String docBaseUri, String conversationBaseUri,
            int viewportWidth, boolean enableContentReadySignal, boolean normalizeMessageWidths,
            boolean enableMungeTables, boolean enableMungeImages) {
        if (!mInProgress) {
            throw new IllegalStateException("must call startConversation first");
        }

        final String contentReadyClass = enableContentReadySignal ? "initial-load" : "";

        append(sConversationLower, contentReadyClass, mContext.getString(R.string.hide_elided),
                mContext.getString(R.string.show_elided), docBaseUri, conversationBaseUri,
                viewportWidth, enableContentReadySignal, normalizeMessageWidths,
                enableMungeTables, enableMungeImages);

        mInProgress = false;

        LogUtils.d(TAG, "rendered conversation of %d bytes, buffer capacity=%d",
                mBuilder.length() << 1, mBuilder.capacity() << 1);

        return emit();
    }
}
