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(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 (EasResponse.isAuthError(status)) {
                // TODO: Handle this gracefully.
                //throw new EasAuthenticationException();
            } else {
                LogUtils.e(TAG, "Meeting response request failed, code: %d", status);
                throw new IOException();
            }
        } finally {
            resp.close();
        }
    }
}
