/*
 * 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 java.io.IOException;
import java.io.InputStream;

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

import com.android.exchange.EasSyncService;
import com.android.exchange.EmailContent.Account;
import com.android.exchange.EmailContent.Mailbox;

/**
 * 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.mSyncFrequency = 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.mSyncFrequency == Account.CHECK_INTERVAL_PUSH) {
                    mMailbox.mSyncFrequency = Account.CHECK_INTERVAL_PING;
                }
           } else {
                skipTag();
           }
        }

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


}
