package com.android.exchange.service;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.SyncResult;
import android.os.Bundle;

import com.android.emailcommon.provider.Account;
import com.android.emailcommon.provider.EmailContent.HostAuthColumns;
import com.android.emailcommon.provider.Mailbox;
import com.android.exchange.CommandStatusException;
import com.android.exchange.CommandStatusException.CommandStatus;
import com.android.exchange.EasResponse;
import com.android.exchange.adapter.FolderSyncParser;
import com.android.exchange.adapter.Serializer;
import com.android.exchange.adapter.Tags;

import org.apache.http.HttpStatus;

import java.io.IOException;
import java.io.InputStream;

/**
 * Performs an Exchange Account sync, which includes folder sync.
 */
public class EasAccountSyncHandler extends EasSyncHandler {


    public EasAccountSyncHandler(final Context context, final ContentResolver contentResolver,
            final Account account, final Mailbox mailbox, final Bundle syncExtras,
            final SyncResult syncResult) {
        super(context, contentResolver, account, mailbox, syncExtras, syncResult);
    }

    @Override
    public SyncStatus performSync() {
        boolean needsResync;
        do {
            needsResync = false;
            final EasResponse resp;
            try {
                final Serializer s = new Serializer();
                s.start(Tags.FOLDER_FOLDER_SYNC).start(Tags.FOLDER_SYNC_KEY)
                    .text(mAccount.mSyncKey).end().end().done();
                resp = sendHttpClientPost("FolderSync", s.toByteArray());
            } catch (final IOException e) {
                return SyncStatus.FAILURE_IO;
            }
            try {
                final int code = resp.getStatus();
                if (code == HttpStatus.SC_OK) {
                    if (!resp.isEmpty()) {
                        final InputStream is = resp.getInputStream();
                        try {
                            // Returns true if we need to sync again
                            // TODO: FolderSyncParser needs to be cleaned up to remove dependency
                            // on AbstractSyncAdapter.
                            if (new FolderSyncParser(mContext, mContentResolver, is, mAccount,
                                    mMailbox, false).parse()) {
                                needsResync = true;
                            }
                        } catch (final IOException e) {
                            return SyncStatus.FAILURE_IO;
                        } catch (final CommandStatusException e) {
                            final int status = e.mStatus;
                            if (CommandStatus.isNeedsProvisioning(status)) {
                                // TODO: Attempt provisioning.
                                return SyncStatus.FAILURE_SECURITY;
                            }
                            return SyncStatus.FAILURE_OTHER;
                        }
                    }
                } else if (EasResponse.isProvisionError(code)) {
                    // TODO: Attempt provisioning.
                    return SyncStatus.FAILURE_SECURITY;
                } else if (EasResponse.isAuthError(code)) {
                    return SyncStatus.FAILURE_LOGIN;
                } else if (EasResponse.isRedirectError(code)) {
                    if (redirectHostAuth(resp.getRedirectAddress())) {
                        needsResync = true;
                    } else {
                        // TODO: Perhaps a more severe error here?
                        return SyncStatus.FAILURE_LOGIN;
                    }
                }
            } finally {
                resp.close();
            }
        } while (needsResync);

        return SyncStatus.SUCCESS;
    }

    /**
     * Reset our local HostAuth's address and save the change to the DB.
     * @param newAddress The new address for the HostAuth.
     * @return Whether the redirect was processed.
     */
    private boolean redirectHostAuth(final String newAddress) {
        if (newAddress != null) {
            mHostAuth.mAddress = newAddress;
            final ContentValues haValues = new ContentValues(1);
            haValues.put(HostAuthColumns.ADDRESS, newAddress);
            mHostAuth.update(mContext, haValues);
            // TODO: When we start caching connections, make sure to uncache here.
        }
        return newAddress != null;
    }

}
