/*
 * Copyright (C) 2008-2009 Marc Blank
 * Licensed to 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.exchange.adapter;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.OperationApplicationException;
import android.os.RemoteException;

import com.android.emailcommon.provider.Account;
import com.android.emailcommon.provider.EmailContent.MailboxColumns;
import com.android.emailcommon.provider.Mailbox;
import com.android.exchange.CommandStatusException;
import com.android.exchange.CommandStatusException.CommandStatus;
import com.android.exchange.Eas;
import com.android.mail.utils.LogUtils;

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

/**
 * Base class for the Email and PIM sync parsers
 * Handles the basic flow of syncKeys, looping to get more data, handling errors, etc.
 * Each subclass must implement a handful of methods that relate specifically to the data type
 *
 */
public abstract class AbstractSyncParser extends Parser {
    private static final String TAG = Eas.LOG_TAG;

    protected Mailbox mMailbox;
    protected Account mAccount;
    protected Context mContext;
    protected ContentResolver mContentResolver;

    private boolean mLooping;

    public AbstractSyncParser(final Context context, final ContentResolver resolver,
            final InputStream in, final Mailbox mailbox, final Account account) throws IOException {
        super(in);
        init(context, resolver, mailbox, account);
    }

    public AbstractSyncParser(InputStream in, AbstractSyncAdapter adapter) throws IOException {
        super(in);
        init(adapter);
    }

    public AbstractSyncParser(Parser p, AbstractSyncAdapter adapter) throws IOException {
        super(p);
        init(adapter);
    }

    private void init(final AbstractSyncAdapter adapter) {
        init(adapter.mContext, adapter.mContext.getContentResolver(), adapter.mMailbox,
                adapter.mAccount);
    }

    private void init(final Context context, final ContentResolver resolver, final Mailbox mailbox,
            final Account account) {
        mContext = context;
        mContentResolver = resolver;
        mMailbox = mailbox;
        mAccount = account;
    }

    /**
     * Read, parse, and act on incoming commands from the Exchange server
     * @throws IOException if the connection is broken
     * @throws CommandStatusException
     */
    public abstract void commandsParser() throws IOException, CommandStatusException;

    /**
     * Read, parse, and act on server responses
     * @throws IOException
     */
    public abstract void responsesParser() throws IOException;

    /**
     * Commit any changes found during parsing
     * @throws IOException
     */
    public abstract void commit() throws IOException, RemoteException,
            OperationApplicationException;

    public boolean isLooping() {
        return mLooping;
    }

    /**
     * Skip through tags until we reach the specified end tag
     * @param endTag the tag we end with
     * @throws IOException
     */
    public void skipParser(int endTag) throws IOException {
        while (nextTag(endTag) != END) {
            skipTag();
        }
    }

    /**
     * Loop through the top-level structure coming from the Exchange server
     * Sync keys and the more available flag are handled here, whereas specific data parsing
     * is handled by abstract methods implemented for each data class (e.g. Email, Contacts, etc.)
     * @throws CommandStatusException
     */
    @Override
    public boolean parse() throws IOException, CommandStatusException {
        int status;
        boolean moreAvailable = false;
        boolean newSyncKey = false;
        mLooping = false;
        // If we're not at the top of the xml tree, throw an exception
        if (nextTag(START_DOCUMENT) != Tags.SYNC_SYNC) {
            throw new EasParserException();
        }

        boolean mailboxUpdated = false;
        ContentValues cv = new ContentValues();

        // Loop here through the remaining xml
        while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
            if (tag == Tags.SYNC_COLLECTION || tag == Tags.SYNC_COLLECTIONS) {
                // Ignore these tags, since we've only got one collection syncing in this loop
            } else if (tag == Tags.SYNC_STATUS) {
                // Status = 1 is success; everything else is a failure
                status = getValueInt();
                if (status != 1) {
                    if (status == 3 || CommandStatus.isBadSyncKey(status)) {
                        // Must delete all of the data and start over with syncKey of "0"
                        mMailbox.mSyncKey = "0";
                        newSyncKey = true;
                        wipe();
                        // Indicate there's more so that we'll start syncing again
                        moreAvailable = true;
                    } else if (status == 16 || status == 5) {
                        // Status 16 indicates a transient server error (indeterminate state)
                        // Status 5 indicates "server error"; this tends to loop for a while so
                        // throwing IOException will at least provide backoff behavior
                        throw new IOException();
                    } else if (status == 8 || status == 12) {
                        // Status 8 is Bad; it means the server doesn't recognize the serverId it
                        // sent us.  12 means that we're being asked to refresh the folder list.
                        // We'll do that with 8 also...
                        // TODO: reloadFolderList simply sets all mailboxes to hold.
                        //ExchangeService.reloadFolderList(mContext, mAccount.mId, true);
                        // We don't have any provision for telling the user "wait a minute while
                        // we sync folders"...
                        throw new IOException();
                    } else if (status == 7) {
                        // TODO: Fix this. The handling here used to be pretty bogus, and it's not
                        // obvious that simply forcing another resync makes sense here.
                        moreAvailable = true;
                    } else {
                        LogUtils.e(LogUtils.TAG, "Sync: Unknown status: " + status);
                        // Access, provisioning, transient, etc.
                        throw new CommandStatusException(status);
                    }
                }
            } else if (tag == Tags.SYNC_COMMANDS) {
                commandsParser();
            } else if (tag == Tags.SYNC_RESPONSES) {
                responsesParser();
            } else if (tag == Tags.SYNC_MORE_AVAILABLE) {
                moreAvailable = true;
            } else if (tag == Tags.SYNC_SYNC_KEY) {
                if (mMailbox.mSyncKey.equals("0")) {
                    moreAvailable = true;
                }
                String newKey = getValue();
                userLog("Parsed key for ", mMailbox.mDisplayName, ": ", newKey);
                if (!newKey.equals(mMailbox.mSyncKey)) {
                    mMailbox.mSyncKey = newKey;
                    cv.put(MailboxColumns.SYNC_KEY, newKey);
                    mailboxUpdated = true;
                    newSyncKey = true;
                }
           } else {
                skipTag();
           }
        }

        // If we don't have a new sync key, ignore moreAvailable (or we'll loop)
        if (moreAvailable && !newSyncKey) {
            LogUtils.e(TAG, "Looping detected");
            mLooping = true;
        }

        // Commit any changes
        try {
            commit();
            if (mailboxUpdated) {
                mMailbox.update(mContext, cv);
            }
        } catch (RemoteException e) {
            LogUtils.e(TAG, "Failed to commit changes", e);
        } catch (OperationApplicationException e) {
            LogUtils.e(TAG, "Failed to commit changes", e);
        }
        // Let the caller know that there's more to do
        if (moreAvailable) {
            userLog("MoreAvailable");
        }
        return moreAvailable;
    }

    abstract protected void wipe();

    void userLog(String ...strings) {
        // TODO: Convert to other logging types?
        //mService.userLog(strings);
    }

    void userLog(String string, int num, String string2) {
        // TODO: Convert to other logging types?
        //mService.userLog(string, num, string2);
    }
}
