/*
 * 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 com.android.email.provider.EmailContent.Account;
import com.android.email.provider.EmailContent.Mailbox;
import com.android.email.provider.EmailContent.MailboxColumns;
import com.android.exchange.EasSyncService;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;

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 EasContentParser extends EasParser {

    EasSyncService mService;

    Mailbox mMailbox;

    Account mAccount;

    Context mContext;

    ContentResolver mContentResolver;

    public EasContentParser(InputStream in, EasSyncService _service) throws IOException {
        super(in);
        mService = _service;
        mContext = mService.mContext;
        mContentResolver = mContext.getContentResolver();
        mMailbox = mService.mMailbox;
        mAccount = mService.mAccount;
    }

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

    /**
     * Read, parse, and act on server responses
     * Email doesn't have any, so this isn't yet implemented anywhere.  It will become abstract,
     * in the near future, however.
     * @throws IOException
     */
    public void responsesParser() throws IOException {
        // Placeholder until needed; will become an abstract method
    }

    /**
     * Delete all records of this class in this account
     */
    public abstract void wipe();

    /**
     * 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.)
     */
    public boolean parse() throws IOException {
        int status;
        boolean moreAvailable = false;
        // If we're not at the top of the xml tree, throw an exception
        if (nextTag(START_DOCUMENT) != EasTags.SYNC_SYNC) {
            throw new IOException();
        }
        // Loop here through the remaining xml
        while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
            if (tag == EasTags.SYNC_COLLECTION || tag == EasTags.SYNC_COLLECTIONS) {
                // Ignore these tags, since we've only got one collection syncing in this loop
            } else if (tag == EasTags.SYNC_STATUS) {
                // Status = 1 is success; everything else is a failure
                status = getValueInt();
                if (status != 1) {
                    mService.errorLog("Sync failed: " + status);
                    // Status = 3 means invalid sync key
                    if (status == 3) {
                        // Must delete all of the data and start over with syncKey of "0"
                        mMailbox.mSyncKey = "0";
                        // Make this a push box through the first sync
                        // TODO Make frequency conditional on user settings!
                        mMailbox.mSyncInterval = Account.CHECK_INTERVAL_PUSH;
                        mService.errorLog("Bad sync key; RESET and delete contacts");
                        wipe();
                        // Indicate there's more so that we'll start syncing again
                        moreAvailable = true;
                    }
                }
            } else if (tag == EasTags.SYNC_COMMANDS) {
                commandsParser();
            } else if (tag == EasTags.SYNC_RESPONSES) {
                responsesParser();
            } else if (tag == EasTags.SYNC_MORE_AVAILABLE) {
                moreAvailable = true;
            } else if (tag == EasTags.SYNC_SYNC_KEY) {
                if (mMailbox.mSyncKey.equals("0"))
                    moreAvailable = true;
                String newKey = getValue();
                mService.userLog("Parsed key for " + mMailbox.mDisplayName + ": " + newKey);
                mMailbox.mSyncKey = newKey;
                // If we were pushing (i.e. auto-start), now we'll become ping-triggered
                if (mMailbox.mSyncInterval == Account.CHECK_INTERVAL_PUSH) {
                    mMailbox.mSyncInterval = Account.CHECK_INTERVAL_PING;
                }
           } else {
                skipTag();
           }
        }

        // Make sure we save away the new syncKey, syncFrequency, etc.
        ContentValues cv = new ContentValues();
        cv.put(MailboxColumns.SYNC_KEY, mMailbox.mSyncKey);
        cv.put(MailboxColumns.SYNC_INTERVAL, mMailbox.mSyncInterval);
        mMailbox.update(mContext, cv);
        mService.userLog(mMailbox.mDisplayName + " SyncKey saved as: " + mMailbox.mSyncKey);
        // Let the caller know that there's more to do
        return moreAvailable;
    }


}
