package com.android.exchange.service;

import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Entity;
import android.provider.CalendarContract.Attendees;
import android.provider.CalendarContract.Events;

import com.android.emailcommon.mail.Address;
import com.android.emailcommon.mail.MeetingInfo;
import com.android.emailcommon.mail.PackedString;
import com.android.emailcommon.provider.Account;
import com.android.emailcommon.provider.EmailContent.MailboxColumns;
import com.android.emailcommon.provider.EmailContent.Message;
import com.android.emailcommon.provider.Mailbox;
import com.android.emailcommon.service.EmailServiceConstants;
import com.android.emailcommon.utility.Utility;
import com.android.exchange.EasResponse;
import com.android.exchange.adapter.MeetingResponseParser;
import com.android.exchange.adapter.Serializer;
import com.android.exchange.adapter.Tags;
import com.android.exchange.utility.CalendarUtilities;
import com.android.mail.providers.UIProvider;
import com.android.mail.utils.LogUtils;

import org.apache.http.HttpStatus;

import java.io.IOException;

/**
 * Responds to a meeting request, both notifying the EAS server and sending email.
 */
public class EasMeetingResponder extends EasServerConnection {

    private static final String TAG = "EasMeetingResponder";

    /** Projection for getting the server id for a mailbox. */
    private static final String[] MAILBOX_SERVER_ID_PROJECTION = { MailboxColumns.SERVER_ID };
    private static final int MAILBOX_SERVER_ID_COLUMN = 0;

    /** EAS protocol values for UserResponse. */
    private static final int EAS_RESPOND_ACCEPT = 1;
    private static final int EAS_RESPOND_TENTATIVE = 2;
    private static final int EAS_RESPOND_DECLINE = 3;

    /** Value to use if we get a UI response value that we can't handle. */
    private static final int EAS_RESPOND_UNKNOWN = -1;

    private EasMeetingResponder(final Context context, final Account account) {
        super(context, account);
    }

    /**
     * Translate from {@link UIProvider.MessageOperations} constants to EAS values.
     * They're currently identical but this is for future-proofing.
     * @param messageOperationResponse The response value that came from the UI.
     * @return The EAS protocol value to use.
     */
    private static int messageOperationResponseToUserResponse(final int messageOperationResponse) {
        switch (messageOperationResponse) {
            case UIProvider.MessageOperations.RESPOND_ACCEPT:
                return EAS_RESPOND_ACCEPT;
            case UIProvider.MessageOperations.RESPOND_TENTATIVE:
                return EAS_RESPOND_TENTATIVE;
            case UIProvider.MessageOperations.RESPOND_DECLINE:
                return EAS_RESPOND_DECLINE;
        }
        return EAS_RESPOND_UNKNOWN;
    }

    /**
     * Send the response to both the EAS server and as email (if appropriate).
     * @param context Our {@link Context}.
     * @param messageId The db id for the message containing the meeting request.
     * @param response The UI's value for the user's response to the meeting.
     */
    public static void sendMeetingResponse(final Context context, final long messageId,
            final int response) {
        final int easResponse = messageOperationResponseToUserResponse(response);
        if (easResponse == EAS_RESPOND_UNKNOWN) {
            LogUtils.e(TAG, "Bad response value: %d", response);
            return;
        }
        final Message msg = Message.restoreMessageWithId(context, messageId);
        if (msg == null) {
            LogUtils.d(TAG, "Could not load message %d", messageId);
            return;
        }
        final Account account = Account.restoreAccountWithId(context, msg.mAccountKey);
        if (account == null) {
            LogUtils.e(TAG, "Could not load account %d for message %d", msg.mAccountKey, msg.mId);
            return;
        }
        final String mailboxServerId = Utility.getFirstRowString(context,
                ContentUris.withAppendedId(Mailbox.CONTENT_URI, msg.mMailboxKey),
                MAILBOX_SERVER_ID_PROJECTION, null, null, null, MAILBOX_SERVER_ID_COLUMN);
        if (mailboxServerId == null) {
            LogUtils.e(TAG, "Could not load mailbox %d for message %d", msg.mMailboxKey, msg.mId);
            return;
        }

        final EasMeetingResponder responder = new EasMeetingResponder(context, account);
        try {
            responder.sendResponse(msg, mailboxServerId, easResponse);
        } catch (final IOException e) {
            LogUtils.e(TAG, "IOException: %s", e.getMessage());
        }
    }

    /**
     * Send an email response to a meeting invitation.
     * @param meetingInfo The meeting info that was extracted from the invitation message.
     * @param response The EAS value for the user's response to the meeting.
     */
    private void sendMeetingResponseMail(final PackedString meetingInfo, final int response) {
        // This will come as "First Last" <box@server.blah>, so we use Address to
        // parse it into parts; we only need the email address part for the ics file
        final Address[] addrs = Address.parse(meetingInfo.get(MeetingInfo.MEETING_ORGANIZER_EMAIL));
        // It shouldn't be possible, but handle it anyway
        if (addrs.length != 1) return;
        final String organizerEmail = addrs[0].getAddress();

        final String dtStamp = meetingInfo.get(MeetingInfo.MEETING_DTSTAMP);
        final String dtStart = meetingInfo.get(MeetingInfo.MEETING_DTSTART);
        final String dtEnd = meetingInfo.get(MeetingInfo.MEETING_DTEND);

        // What we're doing here is to create an Entity that looks like an Event as it would be
        // stored by CalendarProvider
        final ContentValues entityValues = new ContentValues(6);
        final Entity entity = new Entity(entityValues);

        // Fill in times, location, title, and organizer
        entityValues.put("DTSTAMP",
                CalendarUtilities.convertEmailDateTimeToCalendarDateTime(dtStamp));
        entityValues.put(Events.DTSTART, Utility.parseEmailDateTimeToMillis(dtStart));
        entityValues.put(Events.DTEND, Utility.parseEmailDateTimeToMillis(dtEnd));
        entityValues.put(Events.EVENT_LOCATION, meetingInfo.get(MeetingInfo.MEETING_LOCATION));
        entityValues.put(Events.TITLE, meetingInfo.get(MeetingInfo.MEETING_TITLE));
        entityValues.put(Events.ORGANIZER, organizerEmail);

        // Add ourselves as an attendee, using our account email address
        final ContentValues attendeeValues = new ContentValues(2);
        attendeeValues.put(Attendees.ATTENDEE_RELATIONSHIP,
                Attendees.RELATIONSHIP_ATTENDEE);
        attendeeValues.put(Attendees.ATTENDEE_EMAIL, mAccount.mEmailAddress);
        entity.addSubValue(Attendees.CONTENT_URI, attendeeValues);

        // Add the organizer
        final ContentValues organizerValues = new ContentValues(2);
        organizerValues.put(Attendees.ATTENDEE_RELATIONSHIP,
                Attendees.RELATIONSHIP_ORGANIZER);
        organizerValues.put(Attendees.ATTENDEE_EMAIL, organizerEmail);
        entity.addSubValue(Attendees.CONTENT_URI, organizerValues);

        // Create a message from the Entity we've built.  The message will have fields like
        // to, subject, date, and text filled in.  There will also be an "inline" attachment
        // which is in iCalendar format
        final int flag;
        switch(response) {
            case EmailServiceConstants.MEETING_REQUEST_ACCEPTED:
                flag = Message.FLAG_OUTGOING_MEETING_ACCEPT;
                break;
            case EmailServiceConstants.MEETING_REQUEST_DECLINED:
                flag = Message.FLAG_OUTGOING_MEETING_DECLINE;
                break;
            case EmailServiceConstants.MEETING_REQUEST_TENTATIVE:
            default:
                flag = Message.FLAG_OUTGOING_MEETING_TENTATIVE;
                break;
        }
        final Message outgoingMsg =
            CalendarUtilities.createMessageForEntity(mContext, entity, flag,
                    meetingInfo.get(MeetingInfo.MEETING_UID), mAccount);
        // Assuming we got a message back (we might not if the event has been deleted), send it
        if (outgoingMsg != null) {
            sendMessage(mAccount, outgoingMsg);
        }
    }

    /**
     * Send the response to the EAS server, and also via email if requested.
     * @param msg The email message for the meeting invitation.
     * @param mailboxServerId The server id for the mailbox that msg is in.
     * @param response The EAS value for the user's response.
     * @throws IOException
     */
    private void sendResponse(final Message msg, final String mailboxServerId, final int response)
            throws IOException {
        final Serializer s = new Serializer();
        s.start(Tags.MREQ_MEETING_RESPONSE).start(Tags.MREQ_REQUEST);
        s.data(Tags.MREQ_USER_RESPONSE, Integer.toString(response));
        s.data(Tags.MREQ_COLLECTION_ID, mailboxServerId);
        s.data(Tags.MREQ_REQ_ID, msg.mServerId);
        s.end().end().done();
        final EasResponse resp = sendHttpClientPost("MeetingResponse", s.toByteArray());
        try {
            final int status = resp.getStatus();
            if (status == HttpStatus.SC_OK) {
                if (!resp.isEmpty()) {
                    // TODO: Improve the parsing to actually handle error statuses.
                    new MeetingResponseParser(resp.getInputStream()).parse();

                    if (msg.mMeetingInfo != null) {
                        final PackedString meetingInfo = new PackedString(msg.mMeetingInfo);
                        final String responseRequested =
                                meetingInfo.get(MeetingInfo.MEETING_RESPONSE_REQUESTED);
                        // If there's no tag, or a non-zero tag, we send the response mail
                        if (!"0".equals(responseRequested)) {
                            sendMeetingResponseMail(meetingInfo, response);
                        }
                    }
                }
            } else if (resp.isAuthError()) {
                // TODO: Handle this gracefully.
                //throw new EasAuthenticationException();
            } else {
                LogUtils.e(TAG, "Meeting response request failed, code: %d", status);
                throw new IOException();
            }
        } finally {
            resp.close();
        }
    }
}
