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

import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.format.Formatter;
import android.text.style.ForegroundColorSpan;
import android.view.View;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;

import com.android.messaging.R;
import com.android.messaging.datamodel.MessagingContentProvider;
import com.android.messaging.datamodel.data.ConversationMessageData;
import com.android.messaging.datamodel.data.MessageData;
import com.android.messaging.datamodel.data.MessagePartData;
import com.android.messaging.datamodel.media.ImageResource;
import com.android.messaging.datamodel.media.MediaRequest;
import com.android.messaging.datamodel.media.MediaResourceManager;
import com.android.messaging.datamodel.media.MessagePartImageRequestDescriptor;
import com.android.messaging.datamodel.media.MessagePartVideoThumbnailRequestDescriptor;
import com.android.messaging.datamodel.media.UriImageRequestDescriptor;
import com.android.messaging.datamodel.media.VideoThumbnailRequest;
import com.android.messaging.sms.MmsUtils;
import com.android.messaging.ui.UIIntents;
import com.android.messaging.util.AvatarUriUtil;
import com.android.messaging.util.Dates;
import com.android.messaging.util.LogUtil;
import com.android.messaging.util.OsUtil;
import com.android.messaging.util.PhoneUtils;

import java.util.List;

public class WidgetConversationService extends RemoteViewsService {
    private static final String TAG = LogUtil.BUGLE_WIDGET_TAG;

    private static final int IMAGE_ATTACHMENT_SIZE = 400;

    @Override
    public RemoteViewsFactory onGetViewFactory(Intent intent) {
        if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) {
            LogUtil.v(TAG, "onGetViewFactory intent: " + intent);
        }
        return new WidgetConversationFactory(getApplicationContext(), intent);
    }

    /**
     * Remote Views Factory for the conversation widget.
     */
    private static class WidgetConversationFactory extends BaseWidgetFactory {
        private ImageResource mImageResource;
        private String mConversationId;

        public WidgetConversationFactory(Context context, Intent intent) {
            super(context, intent);

            mConversationId = intent.getStringExtra(UIIntents.UI_INTENT_EXTRA_CONVERSATION_ID);
            if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) {
                LogUtil.v(TAG, "BugleFactory intent: " + intent + "widget id: " + mAppWidgetId);
            }
            mIconSize = (int) context.getResources()
                    .getDimension(R.dimen.contact_icon_view_normal_size);
        }

        @Override
        public void onCreate() {
            if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) {
                LogUtil.v(TAG, "onCreate");
            }
            super.onCreate();

            // If the conversation for this widget has been removed, we want to update the widget to
            // "Tap to configure" mode.
            if (!WidgetConversationProvider.isWidgetConfigured(mAppWidgetId)) {
                WidgetConversationProvider.rebuildWidget(mContext, mAppWidgetId);
            }
        }

        @Override
        protected Cursor doQuery() {
            if (TextUtils.isEmpty(mConversationId)) {
                LogUtil.w(TAG, "doQuery no conversation id");
                return null;
            }
            final Uri uri = MessagingContentProvider.buildConversationMessagesUri(mConversationId);
            if (uri != null) {
                LogUtil.w(TAG, "doQuery uri: " + uri.toString());
            }
            return mContext.getContentResolver().query(uri,
                    ConversationMessageData.getProjection(),
                    null,       // where
                    null,       // selection args
                    null        // sort order
                    );
        }

        /**
         * @return the {@link RemoteViews} for a specific position in the list.
         */
        @Override
        public RemoteViews getViewAt(final int originalPosition) {
            synchronized (sWidgetLock) {
                // "View more messages" view.
                if (mCursor == null
                        || (mShouldShowViewMore && originalPosition == 0)) {
                    return getViewMoreItemsView();
                }
                // The message cursor is in reverse order for performance reasons.
                final int position = getCount() - originalPosition - 1;
                if (!mCursor.moveToPosition(position)) {
                    // If we ever fail to move to a position, return the "View More messages"
                    // view.
                    LogUtil.w(TAG, "Failed to move to position: " + position);
                    return getViewMoreItemsView();
                }

                final ConversationMessageData message = new ConversationMessageData();
                message.bind(mCursor);

                // Inflate and fill out the remote view
                final RemoteViews remoteViews = new RemoteViews(
                        mContext.getPackageName(), message.getIsIncoming() ?
                                R.layout.widget_message_item_incoming :
                                    R.layout.widget_message_item_outgoing);

                final boolean hasUnreadMessages = false; //!message.getIsRead();

                // Date
                remoteViews.setTextViewText(R.id.date, boldifyIfUnread(
                        Dates.getWidgetTimeString(message.getReceivedTimeStamp(),
                                false /*abbreviated*/),
                        hasUnreadMessages));

                // On click intent.
                final Intent intent = UIIntents.get().getIntentForConversationActivity(mContext,
                        mConversationId, null /* draft */);

                // Attachments
                int attachmentStringId = 0;
                remoteViews.setViewVisibility(R.id.attachmentFrame, View.GONE);

                int scrollToPosition = originalPosition;
                final int cursorCount = mCursor.getCount();
                if (cursorCount > MAX_ITEMS_TO_SHOW) {
                    scrollToPosition += cursorCount - MAX_ITEMS_TO_SHOW;
                }
                if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) {
                    LogUtil.v(TAG, "getViewAt position: " + originalPosition +
                            " computed position: " + position +
                            " scrollToPosition: " + scrollToPosition +
                            " cursorCount: " + cursorCount +
                            " MAX_ITEMS_TO_SHOW: " + MAX_ITEMS_TO_SHOW);
                }

                intent.putExtra(UIIntents.UI_INTENT_EXTRA_MESSAGE_POSITION, scrollToPosition);
                if (message.hasAttachments()) {
                    final List<MessagePartData> attachments = message.getAttachments();
                    for (MessagePartData part : attachments) {
                        final boolean videoWithThumbnail = part.isVideo()
                                && (VideoThumbnailRequest.shouldShowIncomingVideoThumbnails()
                                || !message.getIsIncoming());
                        if (part.isImage() || videoWithThumbnail) {
                            final Uri uri = part.getContentUri();
                            remoteViews.setViewVisibility(R.id.attachmentFrame, View.VISIBLE);
                            remoteViews.setViewVisibility(R.id.playButton, part.isVideo() ?
                                    View.VISIBLE : View.GONE);
                            remoteViews.setImageViewBitmap(R.id.attachment,
                                    getAttachmentBitmap(part));
                            intent.putExtra(UIIntents.UI_INTENT_EXTRA_ATTACHMENT_URI ,
                                    uri.toString());
                            intent.putExtra(UIIntents.UI_INTENT_EXTRA_ATTACHMENT_TYPE ,
                                    part.getContentType());
                            break;
                        } else if (part.isVideo()) {
                            attachmentStringId = R.string.conversation_list_snippet_video;
                            break;
                        }
                        if (part.isAudio()) {
                            attachmentStringId = R.string.conversation_list_snippet_audio_clip;
                            break;
                        }
                        if (part.isVCard()) {
                            attachmentStringId = R.string.conversation_list_snippet_vcard;
                            break;
                        }
                    }
                }

                remoteViews.setOnClickFillInIntent(message.getIsIncoming() ?
                        R.id.widget_message_item_incoming :
                            R.id.widget_message_item_outgoing,
                        intent);

                // Avatar
                boolean includeAvatar;
                if (OsUtil.isAtLeastJB()) {
                    final Bundle options = mAppWidgetManager.getAppWidgetOptions(mAppWidgetId);
                    if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) {
                        LogUtil.v(TAG, "getViewAt BugleWidgetProvider.WIDGET_SIZE_KEY: " +
                                options.getInt(BugleWidgetProvider.WIDGET_SIZE_KEY));
                    }

                    includeAvatar = options.getInt(BugleWidgetProvider.WIDGET_SIZE_KEY)
                            == BugleWidgetProvider.SIZE_LARGE;
                } else {
                    includeAvatar = true;
                }

                // Show the avatar (and shadow) when grande size, otherwise hide it.
                remoteViews.setViewVisibility(R.id.avatarView, includeAvatar ?
                        View.VISIBLE : View.GONE);
                remoteViews.setViewVisibility(R.id.avatarShadow, includeAvatar ?
                        View.VISIBLE : View.GONE);

                final Uri avatarUri = AvatarUriUtil.createAvatarUri(
                        message.getSenderProfilePhotoUri(),
                        message.getSenderFullName(),
                        message.getSenderNormalizedDestination(),
                        message.getSenderContactLookupKey());

                remoteViews.setImageViewBitmap(R.id.avatarView, includeAvatar ?
                        getAvatarBitmap(avatarUri) : null);

                String text = message.getText();
                if (attachmentStringId != 0) {
                    final String attachment = mContext.getString(attachmentStringId);
                    if (!TextUtils.isEmpty(text)) {
                        text += '\n' + attachment;
                    } else {
                        text = attachment;
                    }
                }

                remoteViews.setViewVisibility(R.id.message, View.VISIBLE);
                updateViewContent(text, message, remoteViews);

                return remoteViews;
            }
        }

        // updateViewContent figures out what to show in the message and date fields based on
        // the message status. This code came from ConversationMessageView.updateViewContent, but
        // had to be simplified to work with our simple widget list item.
        // updateViewContent also builds the accessibility content description for the list item.
        private void updateViewContent(final String messageText,
                final ConversationMessageData message,
                final RemoteViews remoteViews) {
            int titleResId = -1;
            int statusResId = -1;
            boolean showInRed = false;
            String statusText = null;
            switch(message.getStatus()) {
                case MessageData.BUGLE_STATUS_INCOMING_AUTO_DOWNLOADING:
                case MessageData.BUGLE_STATUS_INCOMING_MANUAL_DOWNLOADING:
                case MessageData.BUGLE_STATUS_INCOMING_RETRYING_AUTO_DOWNLOAD:
                case MessageData.BUGLE_STATUS_INCOMING_RETRYING_MANUAL_DOWNLOAD:
                    titleResId = R.string.message_title_downloading;
                    statusResId = R.string.message_status_downloading;
                    break;

                case MessageData.BUGLE_STATUS_INCOMING_YET_TO_MANUAL_DOWNLOAD:
                    if (!OsUtil.isSecondaryUser()) {
                        titleResId = R.string.message_title_manual_download;
                        statusResId = R.string.message_status_download;
                    }
                    break;

                case MessageData.BUGLE_STATUS_INCOMING_EXPIRED_OR_NOT_AVAILABLE:
                    if (!OsUtil.isSecondaryUser()) {
                        titleResId = R.string.message_title_download_failed;
                        statusResId = R.string.message_status_download_error;
                        showInRed = true;
                    }
                    break;

                case MessageData.BUGLE_STATUS_INCOMING_DOWNLOAD_FAILED:
                    if (!OsUtil.isSecondaryUser()) {
                        titleResId = R.string.message_title_download_failed;
                        statusResId = R.string.message_status_download;
                        showInRed = true;
                    }
                    break;

                case MessageData.BUGLE_STATUS_OUTGOING_YET_TO_SEND:
                case MessageData.BUGLE_STATUS_OUTGOING_SENDING:
                    statusResId = R.string.message_status_sending;
                    break;

                case MessageData.BUGLE_STATUS_OUTGOING_RESENDING:
                case MessageData.BUGLE_STATUS_OUTGOING_AWAITING_RETRY:
                    statusResId = R.string.message_status_send_retrying;
                    break;

                case MessageData.BUGLE_STATUS_OUTGOING_FAILED_EMERGENCY_NUMBER:
                    statusResId = R.string.message_status_send_failed_emergency_number;
                    showInRed = true;
                    break;

                case MessageData.BUGLE_STATUS_OUTGOING_FAILED:
                    // don't show the error state unless we're the default sms app
                    if (PhoneUtils.getDefault().isDefaultSmsApp()) {
                        statusResId = MmsUtils.mapRawStatusToErrorResourceId(
                                message.getStatus(), message.getRawTelephonyStatus());
                        showInRed = true;
                        break;
                    }
                    // FALL THROUGH HERE

                case MessageData.BUGLE_STATUS_OUTGOING_COMPLETE:
                case MessageData.BUGLE_STATUS_INCOMING_COMPLETE:
                default:
                    if (!message.getCanClusterWithNextMessage()) {
                        statusText = Dates.getWidgetTimeString(message.getReceivedTimeStamp(),
                                false /*abbreviated*/).toString();
                    }
                    break;
            }

            // Build the content description while we're populating the various fields.
            final StringBuilder description = new StringBuilder();
            final String separator = mContext.getString(R.string.enumeration_comma);
            // Sender information
            final boolean hasPlainTextMessage = !(TextUtils.isEmpty(message.getText()));
            if (message.getIsIncoming()) {
                int senderResId = hasPlainTextMessage
                    ? R.string.incoming_text_sender_content_description
                    : R.string.incoming_sender_content_description;
                description.append(mContext.getString(senderResId, message.getSenderDisplayName()));
            } else {
                int senderResId = hasPlainTextMessage
                    ? R.string.outgoing_text_sender_content_description
                    : R.string.outgoing_sender_content_description;
                description.append(mContext.getString(senderResId));
            }

            final boolean titleVisible = (titleResId >= 0);
            if (titleVisible) {
                final String titleText = mContext.getString(titleResId);
                remoteViews.setTextViewText(R.id.message, titleText);

                final String mmsInfoText = mContext.getString(
                        R.string.mms_info,
                        Formatter.formatFileSize(mContext, message.getSmsMessageSize()),
                        DateUtils.formatDateTime(
                                mContext,
                                message.getMmsExpiry(),
                                DateUtils.FORMAT_SHOW_DATE |
                                DateUtils.FORMAT_SHOW_TIME |
                                DateUtils.FORMAT_NUMERIC_DATE |
                                DateUtils.FORMAT_NO_YEAR));
                remoteViews.setTextViewText(R.id.date, mmsInfoText);
                description.append(separator);
                description.append(mmsInfoText);
            } else if (!TextUtils.isEmpty(messageText)) {
                remoteViews.setTextViewText(R.id.message, messageText);
                description.append(separator);
                description.append(messageText);
            } else {
                remoteViews.setViewVisibility(R.id.message, View.GONE);
            }

            final String subjectText = MmsUtils.cleanseMmsSubject(mContext.getResources(),
                    message.getMmsSubject());
            if (!TextUtils.isEmpty(subjectText)) {
                description.append(separator);
                description.append(subjectText);
            }

            if (statusResId >= 0) {
                statusText = mContext.getString(statusResId);
                final Spannable colorStr = new SpannableString(statusText);
                if (showInRed) {
                    colorStr.setSpan(new ForegroundColorSpan(
                            mContext.getResources().getColor(R.color.timestamp_text_failed)),
                            0, statusText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
                remoteViews.setTextViewText(R.id.date, colorStr);
                description.append(separator);
                description.append(colorStr);
            } else {
                description.append(separator);
                description.append(Dates.getWidgetTimeString(message.getReceivedTimeStamp(),
                        false /*abbreviated*/));
            }

            if (message.hasAttachments()) {
                final List<MessagePartData> attachments = message.getAttachments();
                int stringId;
                for (MessagePartData part : attachments) {
                    if (part.isImage()) {
                        stringId = R.string.conversation_list_snippet_picture;
                    } else if (part.isVideo()) {
                        stringId = R.string.conversation_list_snippet_video;
                    } else if (part.isAudio()) {
                        stringId = R.string.conversation_list_snippet_audio_clip;
                    } else if (part.isVCard()) {
                        stringId = R.string.conversation_list_snippet_vcard;
                    } else {
                        stringId = 0;
                    }
                    if (stringId > 0) {
                        description.append(separator);
                        description.append(mContext.getString(stringId));
                    }
                }
            }
            remoteViews.setContentDescription(message.getIsIncoming() ?
                    R.id.widget_message_item_incoming :
                        R.id.widget_message_item_outgoing, description);
        }

        private Bitmap getAttachmentBitmap(final MessagePartData part) {
            UriImageRequestDescriptor descriptor;
            if (part.isImage()) {
                descriptor = new MessagePartImageRequestDescriptor(part,
                        IMAGE_ATTACHMENT_SIZE, // desiredWidth
                        IMAGE_ATTACHMENT_SIZE,  // desiredHeight
                        true // isStatic
                        );
            } else if (part.isVideo()) {
                descriptor = new MessagePartVideoThumbnailRequestDescriptor(part);
            } else {
                return null;
            }

            final MediaRequest<ImageResource> imageRequest =
                    descriptor.buildSyncMediaRequest(mContext);
            final ImageResource imageResource =
                    MediaResourceManager.get().requestMediaResourceSync(imageRequest);
            if (imageResource != null && imageResource.getBitmap() != null) {
                setImageResource(imageResource);
                return Bitmap.createBitmap(imageResource.getBitmap());
            } else {
                releaseImageResource();
                return null;
            }
        }

        /**
         * @return the "View more messages" view. When the user taps this item, they're
         * taken to the conversation in Bugle.
         */
        @Override
        protected RemoteViews getViewMoreItemsView() {
            if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) {
                LogUtil.v(TAG, "getViewMoreConversationsView");
            }
            final RemoteViews view = new RemoteViews(mContext.getPackageName(),
                    R.layout.widget_loading);
            view.setTextViewText(
                    R.id.loading_text, mContext.getText(R.string.view_more_messages));

            // Tapping this "More messages" item should take us to the conversation.
            final Intent intent = UIIntents.get().getIntentForConversationActivity(mContext,
                    mConversationId, null /* draft */);
            view.setOnClickFillInIntent(R.id.widget_loading, intent);
            return view;
        }

        @Override
        public RemoteViews getLoadingView() {
            final RemoteViews view = new RemoteViews(mContext.getPackageName(),
                    R.layout.widget_loading);
            view.setTextViewText(
                    R.id.loading_text, mContext.getText(R.string.loading_messages));
            return view;
        }

        @Override
        public int getViewTypeCount() {
            return 3;   // Number of different list items that can be returned -
                        // 1- incoming list item
                        // 2- outgoing list item
                        // 3- more items list item
        }

        @Override
        protected int getMainLayoutId() {
            return R.layout.widget_conversation;
        }

        private void setImageResource(final ImageResource resource) {
            if (mImageResource != resource) {
                // Clear out any information for what is currently used
                releaseImageResource();
                mImageResource = resource;
            }
        }

        private void releaseImageResource() {
            if (mImageResource != null) {
                mImageResource.release();
            }
            mImageResource = null;
        }
    }

}
