/*
 * Copyright (C) 2015 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.messaging.datamodel;

import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Typeface;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationCompat.Builder;
import android.support.v4.app.NotificationCompat.WearableExtender;
import android.support.v4.app.NotificationManagerCompat;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.text.style.TextAppearanceSpan;
import android.text.style.URLSpan;

import com.android.messaging.Factory;
import com.android.messaging.R;
import com.android.messaging.datamodel.data.ConversationListItemData;
import com.android.messaging.datamodel.data.ConversationMessageData;
import com.android.messaging.datamodel.data.ConversationParticipantsData;
import com.android.messaging.datamodel.data.MessageData;
import com.android.messaging.datamodel.data.MessagePartData;
import com.android.messaging.datamodel.data.ParticipantData;
import com.android.messaging.datamodel.media.VideoThumbnailRequest;
import com.android.messaging.sms.MmsUtils;
import com.android.messaging.ui.UIIntents;
import com.android.messaging.util.Assert;
import com.android.messaging.util.AvatarUriUtil;
import com.android.messaging.util.BugleGservices;
import com.android.messaging.util.BugleGservicesKeys;
import com.android.messaging.util.ContentType;
import com.android.messaging.util.ConversationIdSet;
import com.android.messaging.util.LogUtil;
import com.android.messaging.util.PendingIntentConstants;
import com.android.messaging.util.UriUtil;
import com.google.common.collect.Lists;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Notification building class for conversation messages.
 *
 * Message Notifications are built in several stages with several utility classes.
 * 1) Perform a database query and fill a data structure with information on messages and
 *    conversations which need to be notified.
 * 2) Based on the data structure choose an appropriate NotificationState subclass to
 *    represent all the notifications.
 *    -- For one or more messages in one conversation: MultiMessageNotificationState.
 *    -- For multiple messages in multiple conversations: MultiConversationNotificationState
 *
 *  A three level structure is used to coalesce the data from the database. From bottom to top:
 *  1) NotificationLineInfo - A single message that needs to be notified.
 *  2) ConversationLineInfo - A list of NotificationLineInfo in a single conversation.
 *  3) ConversationInfoList - A list of ConversationLineInfo and the total number of messages.
 *
 *  The createConversationInfoList function performs the query and creates the data structure.
 */
public abstract class MessageNotificationState extends NotificationState {
    // Logging
    static final String TAG = LogUtil.BUGLE_NOTIFICATIONS_TAG;
    private static final int MAX_MESSAGES_IN_WEARABLE_PAGE = 20;

    private static final int MAX_CHARACTERS_IN_GROUP_NAME = 30;

    private static final int REPLY_INTENT_REQUEST_CODE_OFFSET = 0;
    private static final int NUM_EXTRA_REQUEST_CODES_NEEDED = 1;
    protected String mTickerSender = null;
    protected CharSequence mTickerText = null;
    protected String mTitle = null;
    protected CharSequence mContent = null;
    protected Uri mAttachmentUri = null;
    protected String mAttachmentType = null;
    protected boolean mTickerNoContent;

    @Override
    protected Uri getAttachmentUri() {
        return mAttachmentUri;
    }

    @Override
    protected String getAttachmentType() {
        return mAttachmentType;
    }

    @Override
    public int getIcon() {
        return R.drawable.ic_sms_light;
    }

    @Override
    public int getPriority() {
        // Returning PRIORITY_HIGH causes L to put up a HUD notification. Without it, the ticker
        // isn't displayed.
        return Notification.PRIORITY_HIGH;
    }

    /**
     * Base class for single notification events for messages. Multiple of these
     * may be grouped into a single conversation.
     */
    static class NotificationLineInfo {

        final int mNotificationType;

        NotificationLineInfo() {
            mNotificationType = BugleNotifications.LOCAL_SMS_NOTIFICATION;
        }

        NotificationLineInfo(final int notificationType) {
            mNotificationType = notificationType;
        }
    }

    /**
     * Information on a single chat message which should be shown in a notification.
     */
    static class MessageLineInfo extends NotificationLineInfo {
        final CharSequence mText;
        Uri mAttachmentUri;
        String mAttachmentType;
        final String mAuthorFullName;
        final String mAuthorFirstName;
        boolean mIsManualDownloadNeeded;
        final String mMessageId;

        MessageLineInfo(final boolean isGroup, final String authorFullName,
                final String authorFirstName, final CharSequence text, final Uri attachmentUrl,
                final String attachmentType, final boolean isManualDownloadNeeded,
                final String messageId) {
            super(BugleNotifications.LOCAL_SMS_NOTIFICATION);
            mAuthorFullName = authorFullName;
            mAuthorFirstName = authorFirstName;
            mText = text;
            mAttachmentUri = attachmentUrl;
            mAttachmentType = attachmentType;
            mIsManualDownloadNeeded = isManualDownloadNeeded;
            mMessageId = messageId;
        }
    }

    /**
     * Information on all the notification messages within a single conversation.
     */
    static class ConversationLineInfo {
        // Conversation id of the latest message in the notification for this merged conversation.
        final String mConversationId;

        // True if this represents a group conversation.
        final boolean mIsGroup;

        // Name of the group conversation if available.
        final String mGroupConversationName;

        // True if this conversation's recipients includes one or more email address(es)
        // (see ConversationColumns.INCLUDE_EMAIL_ADDRESS)
        final boolean mIncludeEmailAddress;

        // Timestamp of the latest message
        final long mReceivedTimestamp;

        // Self participant id.
        final String mSelfParticipantId;

        // List of individual line notifications to be parsed later.
        final List<NotificationLineInfo> mLineInfos;

        // Total number of messages. Might be different that mLineInfos.size() as the number of
        // line infos is capped.
        int mTotalMessageCount;

        // Custom ringtone if set
        final String mRingtoneUri;

        // Should notification be enabled for this conversation?
        final boolean mNotificationEnabled;

        // Should notifications vibrate for this conversation?
        final boolean mNotificationVibrate;

        // Avatar uri of sender
        final Uri mAvatarUri;

        // Contact uri of sender
        final Uri mContactUri;

        // Subscription id.
        final int mSubId;

        // Number of participants
        final int mParticipantCount;

        public ConversationLineInfo(final String conversationId,
                final boolean isGroup,
                final String groupConversationName,
                final boolean includeEmailAddress,
                final long receivedTimestamp,
                final String selfParticipantId,
                final String ringtoneUri,
                final boolean notificationEnabled,
                final boolean notificationVibrate,
                final Uri avatarUri,
                final Uri contactUri,
                final int subId,
                final int participantCount) {
            mConversationId = conversationId;
            mIsGroup = isGroup;
            mGroupConversationName = groupConversationName;
            mIncludeEmailAddress = includeEmailAddress;
            mReceivedTimestamp = receivedTimestamp;
            mSelfParticipantId = selfParticipantId;
            mLineInfos = new ArrayList<NotificationLineInfo>();
            mTotalMessageCount = 0;
            mRingtoneUri = ringtoneUri;
            mAvatarUri = avatarUri;
            mContactUri = contactUri;
            mNotificationEnabled = notificationEnabled;
            mNotificationVibrate = notificationVibrate;
            mSubId = subId;
            mParticipantCount = participantCount;
        }

        public int getLatestMessageNotificationType() {
            final MessageLineInfo messageLineInfo = getLatestMessageLineInfo();
            if (messageLineInfo == null) {
                return BugleNotifications.LOCAL_SMS_NOTIFICATION;
            }
            return messageLineInfo.mNotificationType;
        }

        public String getLatestMessageId() {
            final MessageLineInfo messageLineInfo = getLatestMessageLineInfo();
            if (messageLineInfo == null) {
                return null;
            }
            return messageLineInfo.mMessageId;
        }

        public boolean getDoesLatestMessageNeedDownload() {
            final MessageLineInfo messageLineInfo = getLatestMessageLineInfo();
            if (messageLineInfo == null) {
                return false;
            }
            return messageLineInfo.mIsManualDownloadNeeded;
        }

        private MessageLineInfo getLatestMessageLineInfo() {
            // The latest message is stored at index zero of the message line infos.
            if (mLineInfos.size() > 0 && mLineInfos.get(0) instanceof MessageLineInfo) {
                return (MessageLineInfo) mLineInfos.get(0);
            }
            return null;
        }
    }

    /**
     * Information on all the notification messages across all conversations.
     */
    public static class ConversationInfoList {
        final int mMessageCount;
        final List<ConversationLineInfo> mConvInfos;
        public ConversationInfoList(final int count, final List<ConversationLineInfo> infos) {
            mMessageCount = count;
            mConvInfos = infos;
        }
    }

    final ConversationInfoList mConvList;
    private long mLatestReceivedTimestamp;

    private static ConversationIdSet makeConversationIdSet(final ConversationInfoList convList) {
        ConversationIdSet set = null;
        if (convList != null && convList.mConvInfos != null && convList.mConvInfos.size() > 0) {
            set = new ConversationIdSet();
            for (final ConversationLineInfo info : convList.mConvInfos) {
                    set.add(info.mConversationId);
            }
        }
        return set;
    }

    protected MessageNotificationState(final ConversationInfoList convList) {
        super(makeConversationIdSet(convList));
        mConvList = convList;
        mType = PendingIntentConstants.SMS_NOTIFICATION_ID;
        mLatestReceivedTimestamp = Long.MIN_VALUE;
        if (convList != null) {
            for (final ConversationLineInfo info : convList.mConvInfos) {
                mLatestReceivedTimestamp = Math.max(mLatestReceivedTimestamp,
                        info.mReceivedTimestamp);
            }
        }
    }

    @Override
    public long getLatestReceivedTimestamp() {
        return mLatestReceivedTimestamp;
    }

    @Override
    public int getNumRequestCodesNeeded() {
        // Get additional request codes for the Reply PendingIntent (wearables only)
        // and the DND PendingIntent.
        return super.getNumRequestCodesNeeded() + NUM_EXTRA_REQUEST_CODES_NEEDED;
    }

    private int getBaseExtraRequestCode() {
        return mBaseRequestCode + super.getNumRequestCodesNeeded();
    }

    public int getReplyIntentRequestCode() {
        return getBaseExtraRequestCode() + REPLY_INTENT_REQUEST_CODE_OFFSET;
    }

    @Override
    public PendingIntent getClearIntent() {
        return UIIntents.get().getPendingIntentForClearingNotifications(
                    Factory.get().getApplicationContext(),
                    BugleNotifications.UPDATE_MESSAGES,
                    mConversationIds,
                    getClearIntentRequestCode());
    }

    /**
     * Notification for multiple messages in at least 2 different conversations.
     */
    public static class MultiConversationNotificationState extends MessageNotificationState {

        public final List<MessageNotificationState>
                mChildren = new ArrayList<MessageNotificationState>();

        public MultiConversationNotificationState(
                final ConversationInfoList convList, final MessageNotificationState state) {
            super(convList);
            mAttachmentUri = null;
            mAttachmentType = null;

            // Pull the ticker title/text from the single notification
            mTickerSender = state.getTitle();
            mTitle = Factory.get().getApplicationContext().getResources().getQuantityString(
                    R.plurals.notification_new_messages,
                    convList.mMessageCount, convList.mMessageCount);
            mTickerText = state.mContent;

            // Create child notifications for each conversation,
            // which will be displayed (only) on a wearable device.
            for (int i = 0; i < convList.mConvInfos.size(); i++) {
                final ConversationLineInfo convInfo = convList.mConvInfos.get(i);
                if (!(convInfo.mLineInfos.get(0) instanceof MessageLineInfo)) {
                    continue;
                }
                setPeopleForConversation(convInfo.mConversationId);
                final ConversationInfoList list = new ConversationInfoList(
                        convInfo.mTotalMessageCount, Lists.newArrayList(convInfo));
                mChildren.add(new BundledMessageNotificationState(list, i));
            }
        }

        @Override
        public int getIcon() {
            return R.drawable.ic_sms_multi_light;
        }

        @Override
        protected NotificationCompat.Style build(final Builder builder) {
            builder.setContentTitle(mTitle);
            NotificationCompat.InboxStyle inboxStyle = null;
            inboxStyle = new NotificationCompat.InboxStyle(builder);

            final Context context = Factory.get().getApplicationContext();
            // enumeration_comma is defined as ", "
            final String separator = context.getString(R.string.enumeration_comma);
            final StringBuilder senders = new StringBuilder();
            long when = 0;
            for (int i = 0; i < mConvList.mConvInfos.size(); i++) {
                final ConversationLineInfo convInfo = mConvList.mConvInfos.get(i);
                if (convInfo.mReceivedTimestamp > when) {
                    when = convInfo.mReceivedTimestamp;
                }
                String sender;
                CharSequence text;
                final NotificationLineInfo lineInfo = convInfo.mLineInfos.get(0);
                final MessageLineInfo messageLineInfo = (MessageLineInfo) lineInfo;
                if (convInfo.mIsGroup) {
                    sender = (convInfo.mGroupConversationName.length() >
                            MAX_CHARACTERS_IN_GROUP_NAME) ?
                                    truncateGroupMessageName(convInfo.mGroupConversationName)
                                    : convInfo.mGroupConversationName;
                } else {
                    sender = messageLineInfo.mAuthorFullName;
                }
                text = messageLineInfo.mText;
                mAttachmentUri = messageLineInfo.mAttachmentUri;
                mAttachmentType = messageLineInfo.mAttachmentType;

                inboxStyle.addLine(BugleNotifications.formatInboxMessage(
                        sender, text, mAttachmentUri, mAttachmentType));
                if (sender != null) {
                    if (senders.length() > 0) {
                        senders.append(separator);
                    }
                    senders.append(sender);
                }
            }
            // for collapsed state
            mContent = senders;
            builder.setContentText(senders)
                .setTicker(getTicker())
                .setWhen(when);

            return inboxStyle;
        }
    }

    /**
     * Truncate group conversation name to be displayed in the notifications. This either truncates
     * the entire group name or finds the last comma in the available length and truncates the name
     * at that point
     */
    private static String truncateGroupMessageName(final String conversationName) {
        int endIndex = MAX_CHARACTERS_IN_GROUP_NAME;
        for (int i = MAX_CHARACTERS_IN_GROUP_NAME; i >= 0; i--) {
            // The dividing marker should stay consistent with ConversationListItemData.DIVIDER_TEXT
            if (conversationName.charAt(i) == ',') {
                endIndex = i;
                break;
            }
        }
        return conversationName.substring(0, endIndex) + '\u2026';
    }

    /**
     * Notification for multiple messages in a single conversation. Also used if there is a single
     * message in a single conversation.
     */
    public static class MultiMessageNotificationState extends MessageNotificationState {

        public MultiMessageNotificationState(final ConversationInfoList convList) {
            super(convList);
            // This conversation has been accepted.
            final ConversationLineInfo convInfo = convList.mConvInfos.get(0);
            setAvatarUrlsForConversation(convInfo.mConversationId);
            setPeopleForConversation(convInfo.mConversationId);

            final Context context = Factory.get().getApplicationContext();
            MessageLineInfo messageInfo = (MessageLineInfo) convInfo.mLineInfos.get(0);
            // attached photo
            mAttachmentUri = messageInfo.mAttachmentUri;
            mAttachmentType = messageInfo.mAttachmentType;
            mContent = messageInfo.mText;

            if (mAttachmentUri != null) {
                // The default attachment type is an image, since that's what was originally
                // supported. When there's no content type, assume it's an image.
                int message = R.string.notification_picture;
                if (ContentType.isAudioType(mAttachmentType)) {
                    message = R.string.notification_audio;
                } else if (ContentType.isVideoType(mAttachmentType)) {
                    message = R.string.notification_video;
                } else if (ContentType.isVCardType(mAttachmentType)) {
                    message = R.string.notification_vcard;
                }
                final String attachment = context.getString(message);
                final SpannableStringBuilder spanBuilder = new SpannableStringBuilder();
                if (!TextUtils.isEmpty(mContent)) {
                    spanBuilder.append(mContent).append(System.getProperty("line.separator"));
                }
                final int start = spanBuilder.length();
                spanBuilder.append(attachment);
                spanBuilder.setSpan(new StyleSpan(Typeface.ITALIC), start, spanBuilder.length(),
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                mContent = spanBuilder;
            }
            if (convInfo.mIsGroup) {
                // When the message is part of a group, the sender's first name
                // is prepended to the message, but not for the ticker message.
                mTickerText = mContent;
                mTickerSender = messageInfo.mAuthorFullName;
                // append the bold name to the front of the message
                mContent = BugleNotifications.buildSpaceSeparatedMessage(
                        messageInfo.mAuthorFullName, mContent, mAttachmentUri,
                        mAttachmentType);
                mTitle = convInfo.mGroupConversationName;
            } else {
                // No matter how many messages there are, since this is a 1:1, just
                // get the author full name from the first one.
                messageInfo = (MessageLineInfo) convInfo.mLineInfos.get(0);
                mTitle = messageInfo.mAuthorFullName;
            }
        }

        @Override
        protected NotificationCompat.Style build(final Builder builder) {
            builder.setContentTitle(mTitle)
                .setTicker(getTicker());

            NotificationCompat.Style notifStyle = null;
            final ConversationLineInfo convInfo = mConvList.mConvInfos.get(0);
            final List<NotificationLineInfo> lineInfos = convInfo.mLineInfos;
            final int messageCount = lineInfos.size();
            // At this point, all the messages come from the same conversation. We need to load
            // the sender's avatar and then finish building the notification on a callback.

            builder.setContentText(mContent);   // for collapsed state

            if (messageCount == 1) {
                final boolean shouldShowImage = ContentType.isImageType(mAttachmentType)
                        || (ContentType.isVideoType(mAttachmentType)
                        && VideoThumbnailRequest.shouldShowIncomingVideoThumbnails());
                if (mAttachmentUri != null && shouldShowImage) {
                    // Show "Picture" as the content
                    final MessageLineInfo messageLineInfo = (MessageLineInfo) lineInfos.get(0);
                    String authorFirstName = messageLineInfo.mAuthorFirstName;

                    // For the collapsed state, just show "picture" unless this is a
                    // group conversation. If it's a group, show the sender name and
                    // "picture".
                    final CharSequence tickerTag =
                            BugleNotifications.formatAttachmentTag(authorFirstName,
                                    mAttachmentType);
                    // For 1:1 notifications don't show first name in the notification, but
                    // do show it in the ticker text
                    CharSequence pictureTag = tickerTag;
                    if (!convInfo.mIsGroup) {
                        authorFirstName = null;
                        pictureTag = BugleNotifications.formatAttachmentTag(authorFirstName,
                                mAttachmentType);
                    }
                    builder.setContentText(pictureTag);
                    builder.setTicker(tickerTag);

                    notifStyle = new NotificationCompat.BigPictureStyle(builder)
                        .setSummaryText(BugleNotifications.formatInboxMessage(
                                authorFirstName,
                                null, null,
                                null));  // expanded state, just show sender
                } else {
                    notifStyle = new NotificationCompat.BigTextStyle(builder)
                    .bigText(mContent);
                }
            } else {
                // We've got multiple messages for the same sender.
                // Starting with the oldest new message, display the full text of each message.
                // Begin a line for each subsequent message.
                final SpannableStringBuilder buf = new SpannableStringBuilder();

                for (int i = lineInfos.size() - 1; i >= 0; --i) {
                    final NotificationLineInfo info = lineInfos.get(i);
                    final MessageLineInfo messageLineInfo = (MessageLineInfo) info;
                    mAttachmentUri = messageLineInfo.mAttachmentUri;
                    mAttachmentType = messageLineInfo.mAttachmentType;
                    CharSequence text = messageLineInfo.mText;
                    if (!TextUtils.isEmpty(text) || mAttachmentUri != null) {
                        if (convInfo.mIsGroup) {
                            // append the bold name to the front of the message
                            text = BugleNotifications.buildSpaceSeparatedMessage(
                                    messageLineInfo.mAuthorFullName, text, mAttachmentUri,
                                    mAttachmentType);
                        } else {
                            text = BugleNotifications.buildSpaceSeparatedMessage(
                                    null, text, mAttachmentUri, mAttachmentType);
                        }
                        buf.append(text);
                        if (i > 0) {
                            buf.append('\n');
                        }
                    }
                }

                // Show a single notification -- big style with the text of all the messages
                notifStyle = new NotificationCompat.BigTextStyle(builder).bigText(buf);
            }
            builder.setWhen(convInfo.mReceivedTimestamp);
            return notifStyle;
        }

    }

    private static boolean firstNameUsedMoreThanOnce(
            final HashMap<String, Integer> map, final String firstName) {
        if (map == null) {
            return false;
        }
        if (firstName == null) {
            return false;
        }
        final Integer count = map.get(firstName);
        if (count != null) {
            return count > 1;
        } else {
            return false;
        }
    }

    private static HashMap<String, Integer> scanFirstNames(final String conversationId) {
        final Context context = Factory.get().getApplicationContext();
        final Uri uri =
                MessagingContentProvider.buildConversationParticipantsUri(conversationId);
        final Cursor participantsCursor = context.getContentResolver().query(
                uri, ParticipantData.ParticipantsQuery.PROJECTION, null, null, null);
        final ConversationParticipantsData participantsData = new ConversationParticipantsData();
        participantsData.bind(participantsCursor);
        final Iterator<ParticipantData> iter = participantsData.iterator();

        final HashMap<String, Integer> firstNames = new HashMap<String, Integer>();
        boolean seenSelf = false;
        while (iter.hasNext()) {
            final ParticipantData participant = iter.next();
            // Make sure we only add the self participant once
            if (participant.isSelf()) {
                if (seenSelf) {
                    continue;
                } else {
                    seenSelf = true;
                }
            }

            final String firstName = participant.getFirstName();
            if (firstName == null) {
                continue;
            }

            final int currentCount = firstNames.containsKey(firstName)
                    ? firstNames.get(firstName)
                    : 0;
            firstNames.put(firstName, currentCount + 1);
        }
        return firstNames;
    }

    // Essentially, we're building a list of the past 20 messages for this conversation to display
    // on the wearable.
    public static Notification buildConversationPageForWearable(final String conversationId,
            int participantCount) {
        final Context context = Factory.get().getApplicationContext();

        // Limit the number of messages to show. We just want enough to provide context for the
        // notification. Fetch one more than we need, so we can tell if there are more messages
        // before the one we're showing.
        // TODO: in the query, a multipart message will contain a row for each part.
        // We might need a smarter GROUP_BY. On the other hand, we might want to show each of the
        // parts as separate messages on the wearable.
        final int limit = MAX_MESSAGES_IN_WEARABLE_PAGE + 1;

        final List<CharSequence> messages = Lists.newArrayList();
        boolean hasSeenMessagesBeforeNotification = false;
        Cursor convMessageCursor = null;
        try {
            final DatabaseWrapper db = DataModel.get().getDatabase();

            final String[] queryArgs = { conversationId };
            final String convPageSql = ConversationMessageData.getWearableQuerySql() + " LIMIT " +
                    limit;
            convMessageCursor = db.rawQuery(
                    convPageSql,
                    queryArgs);

            if (convMessageCursor == null || !convMessageCursor.moveToFirst()) {
                return null;
            }
            final ConversationMessageData convMessageData =
                    new ConversationMessageData();

            final HashMap<String, Integer> firstNames = scanFirstNames(conversationId);
            do {
                convMessageData.bind(convMessageCursor);

                final String authorFullName = convMessageData.getSenderFullName();
                final String authorFirstName = convMessageData.getSenderFirstName();
                String text = convMessageData.getText();

                final boolean isSmsPushNotification = convMessageData.getIsMmsNotification();

                // if auto-download was off to show a message to tap to download the message. We
                // might need to get that working again.
                if (isSmsPushNotification && text != null) {
                    text = convertHtmlAndStripUrls(text).toString();
                }
                // Skip messages without any content
                if (TextUtils.isEmpty(text) && !convMessageData.hasAttachments()) {
                    continue;
                }
                // Track whether there are messages prior to the one(s) shown in the notification.
                if (convMessageData.getIsSeen()) {
                    hasSeenMessagesBeforeNotification = true;
                }

                final boolean usedMoreThanOnce = firstNameUsedMoreThanOnce(
                        firstNames, authorFirstName);
                String displayName = usedMoreThanOnce ? authorFullName : authorFirstName;
                if (TextUtils.isEmpty(displayName)) {
                    if (convMessageData.getIsIncoming()) {
                        displayName = convMessageData.getSenderDisplayDestination();
                        if (TextUtils.isEmpty(displayName)) {
                            displayName = context.getString(R.string.unknown_sender);
                        }
                    } else {
                        displayName = context.getString(R.string.unknown_self_participant);
                    }
                }

                Uri attachmentUri = null;
                String attachmentType = null;
                final List<MessagePartData> attachments = convMessageData.getAttachments();
                for (final MessagePartData messagePartData : attachments) {
                    // Look for the first attachment that's not the text piece.
                    if (!messagePartData.isText()) {
                        attachmentUri = messagePartData.getContentUri();
                        attachmentType = messagePartData.getContentType();
                        break;
                    }
                }

                final CharSequence message = BugleNotifications.buildSpaceSeparatedMessage(
                        displayName, text, attachmentUri, attachmentType);
                messages.add(message);

            } while (convMessageCursor.moveToNext());
        } finally {
            if (convMessageCursor != null) {
                convMessageCursor.close();
            }
        }

        // If there is no conversation history prior to what is already visible in the main
        // notification, there's no need to include the conversation log, too.
        final int maxMessagesInNotification = getMaxMessagesInConversationNotification();
        if (!hasSeenMessagesBeforeNotification && messages.size() <= maxMessagesInNotification) {
            return null;
        }

        final SpannableStringBuilder bigText = new SpannableStringBuilder();
        // There is at least 1 message prior to the first one that we're going to show.
        // Indicate this by inserting an ellipsis at the beginning of the conversation log.
        if (convMessageCursor.getCount() == limit) {
            bigText.append(context.getString(R.string.ellipsis) + "\n\n");
            if (messages.size() > MAX_MESSAGES_IN_WEARABLE_PAGE) {
                messages.remove(messages.size() - 1);
            }
        }
        // Messages are sorted in descending timestamp order, so iterate backwards
        // to get them back in ascending order for display purposes.
        for (int i = messages.size() - 1; i >= 0; --i) {
            bigText.append(messages.get(i));
            if (i > 0) {
                bigText.append("\n\n");
            }
        }
        ++participantCount;     // Add in myself

        if (participantCount > 2) {
            final SpannableString statusText = new SpannableString(
                    context.getResources().getQuantityString(R.plurals.wearable_participant_count,
                            participantCount, participantCount));
            statusText.setSpan(new ForegroundColorSpan(context.getResources().getColor(
                    R.color.wearable_notification_participants_count)), 0, statusText.length(),
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            bigText.append("\n\n").append(statusText);
        }

        final NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(context);
        final NotificationCompat.Style notifStyle =
                new NotificationCompat.BigTextStyle(notifBuilder).bigText(bigText);
        notifBuilder.setStyle(notifStyle);

        final WearableExtender wearableExtender = new WearableExtender();
        wearableExtender.setStartScrollBottom(true);
        notifBuilder.extend(wearableExtender);

        return notifBuilder.build();
    }

    /**
     * Notification for one or more messages in a single conversation, which is bundled together
     * with notifications for other conversations on a wearable device.
     */
    public static class BundledMessageNotificationState extends MultiMessageNotificationState {
        public int mGroupOrder;
        public BundledMessageNotificationState(final ConversationInfoList convList,
                final int groupOrder) {
            super(convList);
            mGroupOrder = groupOrder;
        }
    }

    /**
     * Performs a query on the database.
     */
    private static ConversationInfoList createConversationInfoList() {
        // Map key is conversation id. We use LinkedHashMap to ensure that entries are iterated in
        // the same order they were originally added. We scan unseen messages from newest to oldest,
        // so the corresponding conversations are added in that order, too.
        final Map<String, ConversationLineInfo> convLineInfos = new LinkedHashMap<>();
        int messageCount = 0;

        Cursor convMessageCursor = null;
        try {
            final Context context = Factory.get().getApplicationContext();
            final DatabaseWrapper db = DataModel.get().getDatabase();

            convMessageCursor = db.rawQuery(
                    ConversationMessageData.getNotificationQuerySql(),
                    null);

            if (convMessageCursor != null && convMessageCursor.moveToFirst()) {
                if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) {
                    LogUtil.v(TAG, "MessageNotificationState: Found unseen message notifications.");
                }
                final ConversationMessageData convMessageData =
                        new ConversationMessageData();

                HashMap<String, Integer> firstNames = null;
                String conversationIdForFirstNames = null;
                String groupConversationName = null;
                final int maxMessages = getMaxMessagesInConversationNotification();

                do {
                    convMessageData.bind(convMessageCursor);

                    // First figure out if this is a valid message.
                    String authorFullName = convMessageData.getSenderFullName();
                    String authorFirstName = convMessageData.getSenderFirstName();
                    final String messageText = convMessageData.getText();

                    final String convId = convMessageData.getConversationId();
                    final String messageId = convMessageData.getMessageId();

                    CharSequence text = messageText;
                    final boolean isManualDownloadNeeded = convMessageData.getIsMmsNotification();
                    if (isManualDownloadNeeded) {
                        // Don't try and convert the text from html if it's sms and not a sms push
                        // notification.
                        Assert.equals(MessageData.BUGLE_STATUS_INCOMING_YET_TO_MANUAL_DOWNLOAD,
                                convMessageData.getStatus());
                        text = context.getResources().getString(
                                R.string.message_title_manual_download);
                    }
                    ConversationLineInfo currConvInfo = convLineInfos.get(convId);
                    if (currConvInfo == null) {
                        final ConversationListItemData convData =
                                ConversationListItemData.getExistingConversation(db, convId);
                        if (!convData.getNotificationEnabled()) {
                            // Skip conversations that have notifications disabled.
                            continue;
                        }
                        final int subId = BugleDatabaseOperations.getSelfSubscriptionId(db,
                                convData.getSelfId());
                        groupConversationName = convData.getName();
                        final Uri avatarUri = AvatarUriUtil.createAvatarUri(
                                convMessageData.getSenderProfilePhotoUri(),
                                convMessageData.getSenderFullName(),
                                convMessageData.getSenderNormalizedDestination(),
                                convMessageData.getSenderContactLookupKey());
                        currConvInfo = new ConversationLineInfo(convId,
                                convData.getIsGroup(),
                                groupConversationName,
                                convData.getIncludeEmailAddress(),
                                convMessageData.getReceivedTimeStamp(),
                                convData.getSelfId(),
                                convData.getNotificationSoundUri(),
                                convData.getNotificationEnabled(),
                                convData.getNotifiationVibrate(),
                                avatarUri,
                                convMessageData.getSenderContactLookupUri(),
                                subId,
                                convData.getParticipantCount());
                        convLineInfos.put(convId, currConvInfo);
                    }
                    // Prepare the message line
                    if (currConvInfo.mTotalMessageCount < maxMessages) {
                        if (currConvInfo.mIsGroup) {
                            if (authorFirstName == null) {
                                // authorFullName might be null as well. In that case, we won't
                                // show an author. That is better than showing all the group
                                // names again on the 2nd line.
                                authorFirstName = authorFullName;
                            }
                        } else {
                            // don't recompute this if we don't need to
                            if (!TextUtils.equals(conversationIdForFirstNames, convId)) {
                                firstNames = scanFirstNames(convId);
                                conversationIdForFirstNames = convId;
                            }
                            if (firstNames != null) {
                                final Integer count = firstNames.get(authorFirstName);
                                if (count != null && count > 1) {
                                    authorFirstName = authorFullName;
                                }
                            }

                            if (authorFullName == null) {
                                authorFullName = groupConversationName;
                            }
                            if (authorFirstName == null) {
                                authorFirstName = groupConversationName;
                            }
                        }
                        final String subjectText = MmsUtils.cleanseMmsSubject(
                                context.getResources(),
                                convMessageData.getMmsSubject());
                        if (!TextUtils.isEmpty(subjectText)) {
                            final String subjectLabel =
                                    context.getString(R.string.subject_label);
                            final SpannableStringBuilder spanBuilder =
                                    new SpannableStringBuilder();

                            spanBuilder.append(context.getString(R.string.notification_subject,
                                    subjectLabel, subjectText));
                            spanBuilder.setSpan(new TextAppearanceSpan(
                                    context, R.style.NotificationSubjectText), 0,
                                    subjectLabel.length(),
                                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                            if (!TextUtils.isEmpty(text)) {
                                // Now add the actual message text below the subject header.
                                spanBuilder.append(System.getProperty("line.separator") + text);
                            }
                            text = spanBuilder;
                        }
                        // If we've got attachments, find the best one. If one of the messages is
                        // a photo, save the url so we'll display a big picture notification.
                        // Otherwise, show the first one we find.
                        Uri attachmentUri = null;
                        String attachmentType = null;
                        final MessagePartData messagePartData =
                                getMostInterestingAttachment(convMessageData);
                        if (messagePartData != null) {
                            attachmentUri = messagePartData.getContentUri();
                            attachmentType = messagePartData.getContentType();
                        }
                        currConvInfo.mLineInfos.add(new MessageLineInfo(currConvInfo.mIsGroup,
                                authorFullName, authorFirstName, text,
                                attachmentUri, attachmentType, isManualDownloadNeeded, messageId));
                    }
                    messageCount++;
                    currConvInfo.mTotalMessageCount++;
                } while (convMessageCursor.moveToNext());
            }
        } finally {
            if (convMessageCursor != null) {
                convMessageCursor.close();
            }
        }
        if (convLineInfos.isEmpty()) {
            return null;
        } else {
            return new ConversationInfoList(messageCount,
                    Lists.newLinkedList(convLineInfos.values()));
        }
    }

    /**
     * Scans all the attachments for a message and returns the most interesting one that we'll
     * show in a notification. By order of importance, in case there are multiple attachments:
     *      1- an image (because we can show the image as a BigPictureNotification)
     *      2- a video (because we can show a video frame as a BigPictureNotification)
     *      3- a vcard
     *      4- an audio attachment
     * @return MessagePartData for the most interesting part. Can be null.
     */
    private static MessagePartData getMostInterestingAttachment(
            final ConversationMessageData convMessageData) {
        final List<MessagePartData> attachments = convMessageData.getAttachments();

        MessagePartData imagePart = null;
        MessagePartData audioPart = null;
        MessagePartData vcardPart = null;
        MessagePartData videoPart = null;

        // 99.99% of the time there will be 0 or 1 part, since receiving slideshows is so
        // uncommon.

        // Remember the first of each type of part.
        for (final MessagePartData messagePartData : attachments) {
            if (messagePartData.isImage() && imagePart == null) {
                imagePart = messagePartData;
            }
            if (messagePartData.isVideo() && videoPart == null) {
                videoPart = messagePartData;
            }
            if (messagePartData.isVCard() && vcardPart == null) {
                vcardPart = messagePartData;
            }
            if (messagePartData.isAudio() && audioPart == null) {
                audioPart = messagePartData;
            }
        }
        if (imagePart != null) {
            return imagePart;
        } else if (videoPart != null) {
            return videoPart;
        } else if (audioPart != null) {
            return audioPart;
        } else if (vcardPart != null) {
            return vcardPart;
        }
        return null;
    }

    private static int getMaxMessagesInConversationNotification() {
        if (!BugleNotifications.isWearCompanionAppInstalled()) {
            return BugleGservices.get().getInt(
                    BugleGservicesKeys.MAX_MESSAGES_IN_CONVERSATION_NOTIFICATION,
                    BugleGservicesKeys.MAX_MESSAGES_IN_CONVERSATION_NOTIFICATION_DEFAULT);
        }
        return BugleGservices.get().getInt(
                BugleGservicesKeys.MAX_MESSAGES_IN_CONVERSATION_NOTIFICATION_WITH_WEARABLE,
                BugleGservicesKeys.MAX_MESSAGES_IN_CONVERSATION_NOTIFICATION_WITH_WEARABLE_DEFAULT);
    }

    /**
     * Scans the database for messages that need to go into notifications. Creates the appropriate
     * MessageNotificationState depending on if there are multiple senders, or
     * messages from one sender.
     * @return NotificationState for the notification created.
     */
    public static NotificationState getNotificationState() {
        MessageNotificationState state = null;
        final ConversationInfoList convList = createConversationInfoList();

        if (convList == null || convList.mConvInfos.size() == 0) {
            if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) {
                LogUtil.v(TAG, "MessageNotificationState: No unseen notifications");
            }
        } else {
            final ConversationLineInfo convInfo = convList.mConvInfos.get(0);
            state = new MultiMessageNotificationState(convList);

            if (convList.mConvInfos.size() > 1) {
                // We've got notifications across multiple conversations. Pass in the notification
                // we just built of the most recent notification so we can use that to show the
                // user the new message in the ticker.
                state = new MultiConversationNotificationState(convList, state);
            } else {
                // For now, only show avatars for notifications for a single conversation.
                if (convInfo.mAvatarUri != null) {
                    if (state.mParticipantAvatarsUris == null) {
                        state.mParticipantAvatarsUris = new ArrayList<Uri>(1);
                    }
                    state.mParticipantAvatarsUris.add(convInfo.mAvatarUri);
                }
                if (convInfo.mContactUri != null) {
                    if (state.mParticipantContactUris == null) {
                        state.mParticipantContactUris = new ArrayList<Uri>(1);
                    }
                    state.mParticipantContactUris.add(convInfo.mContactUri);
                }
            }
        }
        if (state != null && LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) {
            LogUtil.v(TAG, "MessageNotificationState: Notification state created"
                    + ", title = " + LogUtil.sanitizePII(state.mTitle)
                    + ", content = " + LogUtil.sanitizePII(state.mContent.toString()));
        }
        return state;
    }

    protected String getTitle() {
        return mTitle;
    }

    @Override
    public int getLatestMessageNotificationType() {
        // This function is called to determine whether the most recent notification applies
        // to an sms conversation or a hangout conversation. We have different ringtone/vibrate
        // settings for both types of conversations.
        if (mConvList.mConvInfos.size() > 0) {
            final ConversationLineInfo convInfo = mConvList.mConvInfos.get(0);
            return convInfo.getLatestMessageNotificationType();
        }
        return BugleNotifications.LOCAL_SMS_NOTIFICATION;
    }

    @Override
    public String getRingtoneUri() {
        if (mConvList.mConvInfos.size() > 0) {
            return mConvList.mConvInfos.get(0).mRingtoneUri;
        }
        return null;
    }

    @Override
    public boolean getNotificationVibrate() {
        if (mConvList.mConvInfos.size() > 0) {
            return mConvList.mConvInfos.get(0).mNotificationVibrate;
        }
        return false;
    }

    protected CharSequence getTicker() {
        return BugleNotifications.buildColonSeparatedMessage(
                mTickerSender != null ? mTickerSender : mTitle,
                mTickerText != null ? mTickerText : (mTickerNoContent ? null : mContent), null,
                        null);
    }

    private static CharSequence convertHtmlAndStripUrls(final String s) {
        final Spanned text = Html.fromHtml(s);
        if (text instanceof Spannable) {
            stripUrls((Spannable) text);
        }
        return text;
    }

    // Since we don't want to show URLs in notifications, a function
    // to remove them in place.
    private static void stripUrls(final Spannable text) {
        final URLSpan[] spans = text.getSpans(0, text.length(), URLSpan.class);
        for (final URLSpan span : spans) {
            text.removeSpan(span);
        }
    }

    /*
    private static void updateAlertStatusMessages(final long thresholdDeltaMs) {
        // TODO may need this when supporting error notifications
        final EsDatabaseHelper helper = EsDatabaseHelper.getDatabaseHelper();
        final ContentValues values = new ContentValues();
        final long nowMicros = System.currentTimeMillis() * 1000;
        values.put(MessageColumns.ALERT_STATUS, "1");
        final String selection =
                MessageColumns.ALERT_STATUS + "=0 AND (" +
                MessageColumns.STATUS + "=" + EsProvider.MESSAGE_STATUS_FAILED_TO_SEND + " OR (" +
                MessageColumns.STATUS + "!=" + EsProvider.MESSAGE_STATUS_ON_SERVER + " AND " +
                MessageColumns.TIMESTAMP + "+" + thresholdDeltaMs*1000 + "<" + nowMicros + ")) ";

        final int updateCount = helper.getWritableDatabaseWrapper().update(
                EsProvider.MESSAGES_TABLE,
                values,
                selection,
                null);
        if (updateCount > 0) {
            EsConversationsData.notifyConversationsChanged();
        }
    }*/

    static CharSequence applyWarningTextColor(final Context context,
            final CharSequence text) {
        if (text == null) {
            return null;
        }
        final SpannableStringBuilder spanBuilder = new SpannableStringBuilder();
        spanBuilder.append(text);
        spanBuilder.setSpan(new ForegroundColorSpan(context.getResources().getColor(
                R.color.notification_warning_color)), 0, text.length(),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spanBuilder;
    }

    /**
     * Check for failed messages and post notifications as needed.
     * TODO: Rewrite this as a NotificationState.
     */
    public static void checkFailedMessages() {
        final DatabaseWrapper db = DataModel.get().getDatabase();

        final Cursor messageDataCursor = db.query(DatabaseHelper.MESSAGES_TABLE,
            MessageData.getProjection(),
            FailedMessageQuery.FAILED_MESSAGES_WHERE_CLAUSE,
            null /*selectionArgs*/,
            null /*groupBy*/,
            null /*having*/,
            FailedMessageQuery.FAILED_ORDER_BY);

        try {
            final Context context = Factory.get().getApplicationContext();
            final Resources resources = context.getResources();
            final NotificationManagerCompat notificationManager =
                    NotificationManagerCompat.from(context);
            if (messageDataCursor != null) {
                final MessageData messageData = new MessageData();

                final HashSet<String> conversationsWithFailedMessages = new HashSet<String>();

                // track row ids in case we want to display something that requires this
                // information
                final ArrayList<Integer> failedMessages = new ArrayList<Integer>();

                int cursorPosition = -1;
                final long when = 0;

                messageDataCursor.moveToPosition(-1);
                while (messageDataCursor.moveToNext()) {
                    messageData.bind(messageDataCursor);

                    final String conversationId = messageData.getConversationId();
                    if (DataModel.get().isNewMessageObservable(conversationId)) {
                        // Don't post a system notification for an observable conversation
                        // because we already show an angry red annotation in the conversation
                        // itself or in the conversation preview snippet.
                        continue;
                    }

                    cursorPosition = messageDataCursor.getPosition();
                    failedMessages.add(cursorPosition);
                    conversationsWithFailedMessages.add(conversationId);
                }

                if (LogUtil.isLoggable(TAG, LogUtil.DEBUG)) {
                    LogUtil.d(TAG, "Found " + failedMessages.size() + " failed messages");
                }
                if (failedMessages.size() > 0) {
                    final NotificationCompat.Builder builder =
                            new NotificationCompat.Builder(context);

                    CharSequence line1;
                    CharSequence line2;
                    final boolean isRichContent = false;
                    ConversationIdSet conversationIds = null;
                    PendingIntent destinationIntent;
                    if (failedMessages.size() == 1) {
                        messageDataCursor.moveToPosition(cursorPosition);
                        messageData.bind(messageDataCursor);
                        final String conversationId =  messageData.getConversationId();

                        // We have a single conversation, go directly to that conversation.
                        destinationIntent = UIIntents.get()
                                .getPendingIntentForConversationActivity(context,
                                        conversationId,
                                        null /*draft*/);

                        conversationIds = ConversationIdSet.createSet(conversationId);

                        final String failedMessgeSnippet = messageData.getMessageText();
                        int failureStringId;
                        if (messageData.getStatus() ==
                                MessageData.BUGLE_STATUS_INCOMING_DOWNLOAD_FAILED) {
                            failureStringId =
                                    R.string.notification_download_failures_line1_singular;
                        } else {
                            failureStringId = R.string.notification_send_failures_line1_singular;
                        }
                        line1 = resources.getString(failureStringId);
                        line2 = failedMessgeSnippet;
                        // Set rich text for non-SMS messages or MMS push notification messages
                        // which we generate locally with rich text
                        // TODO- fix this
//                        if (messageData.isMmsInd()) {
//                            isRichContent = true;
//                        }
                    } else {
                        // We have notifications for multiple conversation, go to the conversation
                        // list.
                        destinationIntent = UIIntents.get()
                            .getPendingIntentForConversationListActivity(context);

                        int line1StringId;
                        int line2PluralsId;
                        if (messageData.getStatus() ==
                                MessageData.BUGLE_STATUS_INCOMING_DOWNLOAD_FAILED) {
                            line1StringId =
                                    R.string.notification_download_failures_line1_plural;
                            line2PluralsId = R.plurals.notification_download_failures;
                        } else {
                            line1StringId = R.string.notification_send_failures_line1_plural;
                            line2PluralsId = R.plurals.notification_send_failures;
                        }
                        line1 = resources.getString(line1StringId);
                        line2 = resources.getQuantityString(
                                line2PluralsId,
                                conversationsWithFailedMessages.size(),
                                failedMessages.size(),
                                conversationsWithFailedMessages.size());
                    }
                    line1 = applyWarningTextColor(context, line1);
                    line2 = applyWarningTextColor(context, line2);

                    final PendingIntent pendingIntentForDelete =
                            UIIntents.get().getPendingIntentForClearingNotifications(
                                    context,
                                    BugleNotifications.UPDATE_ERRORS,
                                    conversationIds,
                                    0);

                    builder
                        .setContentTitle(line1)
                        .setTicker(line1)
                        .setWhen(when > 0 ? when : System.currentTimeMillis())
                        .setSmallIcon(R.drawable.ic_failed_light)
                        .setDeleteIntent(pendingIntentForDelete)
                        .setContentIntent(destinationIntent)
                        .setSound(UriUtil.getUriForResourceId(context, R.raw.message_failure));
                    if (isRichContent && !TextUtils.isEmpty(line2)) {
                        final NotificationCompat.InboxStyle inboxStyle =
                                new NotificationCompat.InboxStyle(builder);
                        if (line2 != null) {
                            inboxStyle.addLine(Html.fromHtml(line2.toString()));
                        }
                        builder.setStyle(inboxStyle);
                    } else {
                        builder.setContentText(line2);
                    }

                    if (builder != null) {
                        notificationManager.notify(
                                BugleNotifications.buildNotificationTag(
                                        PendingIntentConstants.MSG_SEND_ERROR, null),
                                PendingIntentConstants.MSG_SEND_ERROR,
                                builder.build());
                    }
                } else {
                    notificationManager.cancel(
                            BugleNotifications.buildNotificationTag(
                                    PendingIntentConstants.MSG_SEND_ERROR, null),
                            PendingIntentConstants.MSG_SEND_ERROR);
                }
            }
        } finally {
            if (messageDataCursor != null) {
                messageDataCursor.close();
            }
        }
    }
}
