/**
 * Copyright (c) 2012, Google Inc.
 *
 * 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.mail.providers;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;

import com.android.mail.content.CursorCreator;
import com.android.mail.content.ObjectCursor;
import com.android.mail.providers.UIProvider.AccountCapabilities;
import com.android.mail.providers.UIProvider.AccountColumns;
import com.android.mail.providers.UIProvider.SyncStatus;
import com.android.mail.utils.LogTag;
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.Utils;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Account implements Parcelable {
    private static final String SETTINGS_KEY = "settings";

    /**
     * Human readable account name. Not guaranteed to be the account's email address, nor to match
     * the system account manager.
     */
    // TODO: Make this private and add getDisplayName() accessor
    public final String name;

    /**
     * The real name associated with the account, e.g. "John Doe"
     */
    private final String senderName;

    /**
     * Account manager name. MUST MATCH SYSTEM ACCOUNT MANAGER NAME
     */

    private final String accountManagerName;

    /**
     * Account type. MUST MATCH SYSTEM ACCOUNT MANAGER TYPE
     */

    private final String type;

    /**
     * Cached android.accounts.Account based on the above two values
     */

    private android.accounts.Account amAccount;

    /**
     * The version of the UI provider schema from which this account provider
     * will return results.
     */
    public final int providerVersion;

    /**
     * The uri to directly access the information for this account.
     */
    public final Uri uri;

    /**
     * The possible capabilities that this account supports.
     */
    public final int capabilities;

    /**
     * The content provider uri to return the list of top level folders for this
     * account.
     */
    public final Uri folderListUri;
    /**
     * The content provider uri to return the list of all real folders for this
     * account.
     */
    public Uri fullFolderListUri;
    /**
     * The content provider uri to return the list of all real and synthetic folders for this
     * account.
     */
    public Uri allFolderListUri;
    /**
     * The content provider uri that can be queried for search results.
     */
    public final Uri searchUri;

    /**
     * The custom from addresses for this account or null if there are none.
     */
    public String accountFromAddresses;

    /**
     * The content provider uri that can be used to expunge message from this
     * account. NOTE: This might be better to be an update operation on the
     * messageUri.
     */
    public final Uri expungeMessageUri;

    /**
     * The content provider uri that can be used to undo the last operation
     * performed.
     */
    public final Uri undoUri;

    /**
     * Uri for EDIT intent that will cause the settings screens for this account type to be
     * shown.
     */
    public final Uri settingsIntentUri;

    /**
     * Uri for VIEW intent that will cause the help screens for this account type to be
     * shown.
     */
    public final Uri helpIntentUri;

    /**
     * Uri for VIEW intent that will cause the send feedback screens for this account type to be
     * shown.
     */
    public final Uri sendFeedbackIntentUri;

    /**
     * Uri for VIEW intent that will cause the reauthentication screen for this account to be
     * shown.
     */
    public final Uri reauthenticationIntentUri;

    /**
     * The sync status of the account
     */
    public final int syncStatus;

    /**
     * Uri for VIEW intent that will cause the compose screen for this account type to be
     * shown.
     */
    public final Uri composeIntentUri;

    public final String mimeType;
    /**
     * URI for recent folders for this account.
     */
    public final Uri recentFolderListUri;
    /**
     * The color used for this account in combined view (Email)
     */
    public final int color;
    /**
     * URI for default recent folders for this account, if any.
     */
    public final Uri defaultRecentFolderListUri;
    /**
     * Settings object for this account.
     */
    public final Settings settings;

    /**
     * URI for forcing a manual sync of this account.
     */
    public final Uri manualSyncUri;

    /**
     * URI for account type specific supplementary account info on outgoing links, if any.
     */
    public final Uri viewIntentProxyUri;

    /**
     * URI for querying for the account cookies to be used when displaying inline content in a
     * conversation
     */
    public final Uri accoutCookieQueryUri;

    /**
     * URI to be used with an update() ContentResolver call with a {@link ContentValues} object
     * where the keys are from the {@link AccountColumns.SettingsColumns}, and the values are the
     * new values.
     */
    public final Uri updateSettingsUri;

    /**
     * Whether message transforms (HTML DOM manipulation) feature is enabled.
     */
    public final int enableMessageTransforms;

    /**
     * Sync authority used by the mail app.  This can be used in
     * {@link ContentResolver#getSyncAutomatically} calls to check for whether sync is enabled
     * for this account and mail app.
     */
    public final String syncAuthority;

    public final Uri quickResponseUri;

    /**
     * Transient cache of parsed {@link #accountFromAddresses}, plus an entry for the main account
     * address.
     */
    private transient List<ReplyFromAccount> mReplyFroms;

    private static final String LOG_TAG = LogTag.getLogTag();

    /**
     * Return a serialized String for this account.
     */
    public synchronized String serialize() {
        JSONObject json = new JSONObject();
        try {
            json.put(AccountColumns.NAME, name);
            json.put(AccountColumns.TYPE, type);
            json.put(AccountColumns.SENDER_NAME, senderName);
            json.put(AccountColumns.ACCOUNT_MANAGER_NAME, accountManagerName);
            json.put(AccountColumns.PROVIDER_VERSION, providerVersion);
            json.put(AccountColumns.URI, uri);
            json.put(AccountColumns.CAPABILITIES, capabilities);
            json.put(AccountColumns.FOLDER_LIST_URI, folderListUri);
            json.put(AccountColumns.FULL_FOLDER_LIST_URI, fullFolderListUri);
            json.put(AccountColumns.ALL_FOLDER_LIST_URI, allFolderListUri);
            json.put(AccountColumns.SEARCH_URI, searchUri);
            json.put(AccountColumns.ACCOUNT_FROM_ADDRESSES, accountFromAddresses);
            json.put(AccountColumns.EXPUNGE_MESSAGE_URI, expungeMessageUri);
            json.put(AccountColumns.UNDO_URI, undoUri);
            json.put(AccountColumns.SETTINGS_INTENT_URI, settingsIntentUri);
            json.put(AccountColumns.HELP_INTENT_URI, helpIntentUri);
            json.put(AccountColumns.SEND_FEEDBACK_INTENT_URI, sendFeedbackIntentUri);
            json.put(AccountColumns.REAUTHENTICATION_INTENT_URI, reauthenticationIntentUri);
            json.put(AccountColumns.SYNC_STATUS, syncStatus);
            json.put(AccountColumns.COMPOSE_URI, composeIntentUri);
            json.put(AccountColumns.MIME_TYPE, mimeType);
            json.put(AccountColumns.RECENT_FOLDER_LIST_URI, recentFolderListUri);
            json.put(AccountColumns.COLOR, color);
            json.put(AccountColumns.DEFAULT_RECENT_FOLDER_LIST_URI, defaultRecentFolderListUri);
            json.put(AccountColumns.MANUAL_SYNC_URI, manualSyncUri);
            json.put(AccountColumns.VIEW_INTENT_PROXY_URI, viewIntentProxyUri);
            json.put(AccountColumns.ACCOUNT_COOKIE_QUERY_URI, accoutCookieQueryUri);
            json.put(AccountColumns.UPDATE_SETTINGS_URI, updateSettingsUri);
            json.put(AccountColumns.ENABLE_MESSAGE_TRANSFORMS, enableMessageTransforms);
            json.put(AccountColumns.SYNC_AUTHORITY, syncAuthority);
            json.put(AccountColumns.QUICK_RESPONSE_URI, quickResponseUri);
            if (settings != null) {
                json.put(SETTINGS_KEY, settings.toJSON());
            }
        } catch (JSONException e) {
            LogUtils.wtf(LOG_TAG, e, "Could not serialize account with name %s", name);
        }
        return json.toString();
    }

    /**
     * Create a new instance of an Account object using a serialized instance created previously
     * using {@link #serialize()}. This returns null if the serialized instance was invalid or does
     * not represent a valid account object.
     *
     * @param serializedAccount JSON encoded account object
     * @return Account object
     */
    public static Account newinstance(String serializedAccount) {
        // The heavy lifting is done by Account(name, type, json). This method
        // is a wrapper to check for errors and exceptions and return back a null in cases
        // something breaks.
        try {
            final JSONObject json = new JSONObject(serializedAccount);
            final String name = (String) json.get(UIProvider.AccountColumns.NAME);
            final String type = (String) json.get(UIProvider.AccountColumns.TYPE);
            return new Account(name, type, json);
        } catch (JSONException e) {
            LogUtils.w(LOG_TAG, e, "Could not create an account from this input: \"%s\"",
                    serializedAccount);
            return null;
        }
    }

    /**
     * Construct a new Account instance from a previously serialized string. This calls
     * {@link android.accounts.Account#Account(String, String)} with name and type given as the
     * first two arguments.
     *
     * <p>
     * This is private. Public uses should go through the safe {@link #newinstance(String)} method.
     * </p>
     * @param acctName name of account in {@link android.accounts.Account}
     * @param acctType type of account in {@link android.accounts.Account}
     * @param {@link JSONObject} representing a valid account.
     * @throws JSONException
     */
    private Account(String acctName, String acctType, JSONObject json) throws JSONException {
        name = acctName;
        type = acctType;
        senderName = json.optString(AccountColumns.SENDER_NAME);
        final String amName = json.optString(AccountColumns.ACCOUNT_MANAGER_NAME);
        // We need accountManagerName to be filled in, but we might be dealing with an old cache
        // entry which doesn't have it, so use the display name instead in that case as a fallback
        if (TextUtils.isEmpty(amName)) {
            accountManagerName = name;
        } else {
            accountManagerName = amName;
        }
        providerVersion = json.getInt(AccountColumns.PROVIDER_VERSION);
        uri = Uri.parse(json.optString(AccountColumns.URI));
        capabilities = json.getInt(AccountColumns.CAPABILITIES);
        folderListUri = Utils
                .getValidUri(json.optString(AccountColumns.FOLDER_LIST_URI));
        fullFolderListUri = Utils.getValidUri(json
                .optString(AccountColumns.FULL_FOLDER_LIST_URI));
        allFolderListUri = Utils.getValidUri(json
                .optString(AccountColumns.ALL_FOLDER_LIST_URI));
        searchUri = Utils.getValidUri(json.optString(AccountColumns.SEARCH_URI));
        accountFromAddresses = json.optString(AccountColumns.ACCOUNT_FROM_ADDRESSES,
                "");
        expungeMessageUri = Utils.getValidUri(json
                .optString(AccountColumns.EXPUNGE_MESSAGE_URI));
        undoUri = Utils.getValidUri(json.optString(AccountColumns.UNDO_URI));
        settingsIntentUri = Utils.getValidUri(json
                .optString(AccountColumns.SETTINGS_INTENT_URI));
        helpIntentUri = Utils.getValidUri(json.optString(AccountColumns.HELP_INTENT_URI));
        sendFeedbackIntentUri = Utils.getValidUri(json
                .optString(AccountColumns.SEND_FEEDBACK_INTENT_URI));
        reauthenticationIntentUri = Utils.getValidUri(
                json.optString(AccountColumns.REAUTHENTICATION_INTENT_URI));
        syncStatus = json.optInt(AccountColumns.SYNC_STATUS);
        composeIntentUri = Utils.getValidUri(json.optString(AccountColumns.COMPOSE_URI));
        mimeType = json.optString(AccountColumns.MIME_TYPE);
        recentFolderListUri = Utils.getValidUri(json
                .optString(AccountColumns.RECENT_FOLDER_LIST_URI));
        color = json.optInt(AccountColumns.COLOR, 0);
        defaultRecentFolderListUri = Utils.getValidUri(json
                .optString(AccountColumns.DEFAULT_RECENT_FOLDER_LIST_URI));
        manualSyncUri = Utils
                .getValidUri(json.optString(AccountColumns.MANUAL_SYNC_URI));
        viewIntentProxyUri = Utils
                .getValidUri(json.optString(AccountColumns.VIEW_INTENT_PROXY_URI));
        accoutCookieQueryUri = Utils.getValidUri(
                json.optString(AccountColumns.ACCOUNT_COOKIE_QUERY_URI));
        updateSettingsUri = Utils.getValidUri(
                json.optString(AccountColumns.UPDATE_SETTINGS_URI));
        enableMessageTransforms = json.optInt(AccountColumns.ENABLE_MESSAGE_TRANSFORMS);
        syncAuthority = json.optString(AccountColumns.SYNC_AUTHORITY);
        quickResponseUri = Utils.getValidUri(json.optString(AccountColumns.QUICK_RESPONSE_URI));

        final Settings jsonSettings = Settings.newInstance(json.optJSONObject(SETTINGS_KEY));
        if (jsonSettings != null) {
            settings = jsonSettings;
        } else {
            LogUtils.e(LOG_TAG, new Throwable(),
                    "Unexpected null settings in Account(name, type, jsonAccount)");
            settings = Settings.EMPTY_SETTINGS;
        }
    }

    public Account(Cursor cursor) {
        name = cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.NAME));
        senderName = cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.SENDER_NAME));
        type = cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.TYPE));
        accountManagerName = cursor.getString(
                cursor.getColumnIndex(UIProvider.AccountColumns.ACCOUNT_MANAGER_NAME));
        accountFromAddresses = cursor.getString(
                cursor.getColumnIndex(UIProvider.AccountColumns.ACCOUNT_FROM_ADDRESSES));

        final int capabilitiesColumnIndex =
                cursor.getColumnIndex(UIProvider.AccountColumns.CAPABILITIES);
        if (capabilitiesColumnIndex != -1) {
            capabilities = cursor.getInt(capabilitiesColumnIndex);
        } else {
            capabilities = 0;
        }

        providerVersion =
                cursor.getInt(cursor.getColumnIndex(UIProvider.AccountColumns.PROVIDER_VERSION));
        uri = Uri.parse(cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.URI)));
        folderListUri = Uri.parse(
                cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.FOLDER_LIST_URI)));
        fullFolderListUri = Utils.getValidUri(cursor.getString(
                cursor.getColumnIndex(UIProvider.AccountColumns.FULL_FOLDER_LIST_URI)));
        allFolderListUri = Utils.getValidUri(cursor.getString(
                cursor.getColumnIndex(UIProvider.AccountColumns.ALL_FOLDER_LIST_URI)));
        searchUri = Utils.getValidUri(
                cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.SEARCH_URI)));
        expungeMessageUri = Utils.getValidUri(cursor.getString(
                cursor.getColumnIndex(UIProvider.AccountColumns.EXPUNGE_MESSAGE_URI)));
        undoUri = Utils.getValidUri(
                cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.UNDO_URI)));
        settingsIntentUri = Utils.getValidUri(cursor.getString(
                cursor.getColumnIndex(UIProvider.AccountColumns.SETTINGS_INTENT_URI)));
        helpIntentUri = Utils.getValidUri(
                cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.HELP_INTENT_URI)));
        sendFeedbackIntentUri = Utils.getValidUri(cursor.getString(
                cursor.getColumnIndex(UIProvider.AccountColumns.SEND_FEEDBACK_INTENT_URI)));
        reauthenticationIntentUri = Utils.getValidUri(cursor.getString(
                cursor.getColumnIndex(UIProvider.AccountColumns.REAUTHENTICATION_INTENT_URI)));
        syncStatus = cursor.getInt(cursor.getColumnIndex(UIProvider.AccountColumns.SYNC_STATUS));
        composeIntentUri = Utils.getValidUri(
                cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.COMPOSE_URI)));
        mimeType = cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.MIME_TYPE));
        recentFolderListUri = Utils.getValidUri(cursor.getString(
                cursor.getColumnIndex(UIProvider.AccountColumns.RECENT_FOLDER_LIST_URI)));
        color = cursor.getInt(cursor.getColumnIndex(UIProvider.AccountColumns.COLOR));
        defaultRecentFolderListUri = Utils.getValidUri(cursor.getString(
                cursor.getColumnIndex(UIProvider.AccountColumns.DEFAULT_RECENT_FOLDER_LIST_URI)));
        manualSyncUri = Utils.getValidUri(
                cursor.getString(cursor.getColumnIndex(UIProvider.AccountColumns.MANUAL_SYNC_URI)));
        viewIntentProxyUri = Utils.getValidUri(cursor.getString(
                cursor.getColumnIndex(UIProvider.AccountColumns.VIEW_INTENT_PROXY_URI)));
        accoutCookieQueryUri = Utils.getValidUri(cursor.getString(
                cursor.getColumnIndex(UIProvider.AccountColumns.ACCOUNT_COOKIE_QUERY_URI)));
        updateSettingsUri = Utils.getValidUri(cursor.getString(
                cursor.getColumnIndex(UIProvider.AccountColumns.UPDATE_SETTINGS_URI)));
        enableMessageTransforms = cursor.getInt(
                cursor.getColumnIndex(AccountColumns.ENABLE_MESSAGE_TRANSFORMS));
        syncAuthority = cursor.getString(
                cursor.getColumnIndex(AccountColumns.SYNC_AUTHORITY));
        if (TextUtils.isEmpty(syncAuthority)) {
            // NOTE: this is actually expected in Email for the "combined view" account only
            LogUtils.e(LOG_TAG, "Unexpected empty syncAuthority from cursor");
        }
        quickResponseUri = Utils.getValidUri(cursor.getString(
                cursor.getColumnIndex(AccountColumns.QUICK_RESPONSE_URI)));
        settings = new Settings(cursor);
    }

    /**
     * Returns an array of all Accounts located at this cursor. This method returns a zero length
     * array if no account was found.  This method does not close the cursor.
     * @param cursor cursor pointing to the list of accounts
     * @return the array of all accounts stored at this cursor.
     */
    public static Account[] getAllAccounts(ObjectCursor<Account> cursor) {
        final int initialLength = cursor.getCount();
        if (initialLength <= 0 || !cursor.moveToFirst()) {
            // Return zero length account array rather than null
            return new Account[0];
        }

        final Account[] allAccounts = new Account[initialLength];
        int i = 0;
        do {
            allAccounts[i++] = cursor.getModel();
        } while (cursor.moveToNext());
        // Ensure that the length of the array is accurate
        assert (i == initialLength);
        return allAccounts;
    }

    public android.accounts.Account getAccountManagerAccount() {
        if (amAccount == null) {
            // We don't really need to synchronize this
            // as worst case is we'd create an extra identical object and throw it away
            amAccount = new android.accounts.Account(accountManagerName, type);
        }
        return amAccount;
    }

    public boolean supportsCapability(int capability) {
        return (capabilities & capability) != 0;
    }

    public boolean isAccountSyncRequired() {
        return (syncStatus & SyncStatus.INITIAL_SYNC_NEEDED) == SyncStatus.INITIAL_SYNC_NEEDED;
    }

    public boolean isAccountInitializationRequired() {
        return (syncStatus & SyncStatus.ACCOUNT_INITIALIZATION_REQUIRED) ==
                SyncStatus.ACCOUNT_INITIALIZATION_REQUIRED;
    }

    /**
     * Returns true when when the UI provider has indicated that the account has been initialized,
     * and sync is not required.
     */
    public boolean isAccountReady() {
        return !isAccountInitializationRequired() && !isAccountSyncRequired();
    }

    public Account(Parcel in, ClassLoader loader) {
        name = in.readString();
        senderName = in.readString();
        type = in.readString();
        accountManagerName = in.readString();
        providerVersion = in.readInt();
        uri = in.readParcelable(null);
        capabilities = in.readInt();
        folderListUri = in.readParcelable(null);
        fullFolderListUri = in.readParcelable(null);
        allFolderListUri = in.readParcelable(null);
        searchUri = in.readParcelable(null);
        accountFromAddresses = in.readString();
        expungeMessageUri = in.readParcelable(null);
        undoUri = in.readParcelable(null);
        settingsIntentUri = in.readParcelable(null);
        helpIntentUri = in.readParcelable(null);
        sendFeedbackIntentUri = in.readParcelable(null);
        reauthenticationIntentUri = in.readParcelable(null);
        syncStatus = in.readInt();
        composeIntentUri = in.readParcelable(null);
        mimeType = in.readString();
        recentFolderListUri = in.readParcelable(null);
        color = in.readInt();
        defaultRecentFolderListUri = in.readParcelable(null);
        manualSyncUri = in.readParcelable(null);
        viewIntentProxyUri = in.readParcelable(null);
        accoutCookieQueryUri = in.readParcelable(null);
        updateSettingsUri = in.readParcelable(null);
        enableMessageTransforms = in.readInt();
        syncAuthority = in.readString();
        if (TextUtils.isEmpty(syncAuthority)) {
            LogUtils.e(LOG_TAG, "Unexpected empty syncAuthority from Parcel");
        }
        quickResponseUri = in.readParcelable(null);
        final int hasSettings = in.readInt();
        if (hasSettings == 0) {
            LogUtils.e(LOG_TAG, new Throwable(), "Unexpected null settings in Account(Parcel)");
            settings = Settings.EMPTY_SETTINGS;
        } else {
            settings = in.readParcelable(loader);
        }
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeString(senderName);
        dest.writeString(type);
        dest.writeString(accountManagerName);
        dest.writeInt(providerVersion);
        dest.writeParcelable(uri, 0);
        dest.writeInt(capabilities);
        dest.writeParcelable(folderListUri, 0);
        dest.writeParcelable(fullFolderListUri, 0);
        dest.writeParcelable(allFolderListUri, 0);
        dest.writeParcelable(searchUri, 0);
        dest.writeString(accountFromAddresses);
        dest.writeParcelable(expungeMessageUri, 0);
        dest.writeParcelable(undoUri, 0);
        dest.writeParcelable(settingsIntentUri, 0);
        dest.writeParcelable(helpIntentUri, 0);
        dest.writeParcelable(sendFeedbackIntentUri, 0);
        dest.writeParcelable(reauthenticationIntentUri, 0);
        dest.writeInt(syncStatus);
        dest.writeParcelable(composeIntentUri, 0);
        dest.writeString(mimeType);
        dest.writeParcelable(recentFolderListUri, 0);
        dest.writeInt(color);
        dest.writeParcelable(defaultRecentFolderListUri, 0);
        dest.writeParcelable(manualSyncUri, 0);
        dest.writeParcelable(viewIntentProxyUri, 0);
        dest.writeParcelable(accoutCookieQueryUri, 0);
        dest.writeParcelable(updateSettingsUri, 0);
        dest.writeInt(enableMessageTransforms);
        dest.writeString(syncAuthority);
        dest.writeParcelable(quickResponseUri, 0);
        if (settings == null) {
            LogUtils.e(LOG_TAG, "unexpected null settings object in writeToParcel");
            dest.writeInt(0);
        } else {
            dest.writeInt(1);
            dest.writeParcelable(settings, 0);
        }
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public String toString() {
        // JSON is readable enough.
        return serialize();
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }

        if ((o == null) || (o.getClass() != this.getClass())) {
            return false;
        }

        final Account other = (Account) o;
        return TextUtils.equals(name, other.name) &&
                TextUtils.equals(senderName, other.senderName) &&
                TextUtils.equals(accountManagerName, other.accountManagerName) &&
                TextUtils.equals(type, other.type) &&
                capabilities == other.capabilities &&
                providerVersion == other.providerVersion &&
                Objects.equal(uri, other.uri) &&
                Objects.equal(folderListUri, other.folderListUri) &&
                Objects.equal(fullFolderListUri, other.fullFolderListUri) &&
                Objects.equal(allFolderListUri, other.allFolderListUri) &&
                Objects.equal(searchUri, other.searchUri) &&
                Objects.equal(accountFromAddresses, other.accountFromAddresses) &&
                Objects.equal(expungeMessageUri, other.expungeMessageUri) &&
                Objects.equal(undoUri, other.undoUri) &&
                Objects.equal(settingsIntentUri, other.settingsIntentUri) &&
                Objects.equal(helpIntentUri, other.helpIntentUri) &&
                Objects.equal(sendFeedbackIntentUri, other.sendFeedbackIntentUri) &&
                Objects.equal(reauthenticationIntentUri, other.reauthenticationIntentUri) &&
                (syncStatus == other.syncStatus) &&
                Objects.equal(composeIntentUri, other.composeIntentUri) &&
                TextUtils.equals(mimeType, other.mimeType) &&
                Objects.equal(recentFolderListUri, other.recentFolderListUri) &&
                color == other.color &&
                Objects.equal(defaultRecentFolderListUri, other.defaultRecentFolderListUri) &&
                Objects.equal(viewIntentProxyUri, other.viewIntentProxyUri) &&
                Objects.equal(accoutCookieQueryUri, other.accoutCookieQueryUri) &&
                Objects.equal(updateSettingsUri, other.updateSettingsUri) &&
                Objects.equal(enableMessageTransforms, other.enableMessageTransforms) &&
                Objects.equal(syncAuthority, other.syncAuthority) &&
                Objects.equal(quickResponseUri, other.quickResponseUri) &&
                Objects.equal(settings, other.settings);
    }

    /**
     * Returns true if the two accounts differ in sync or server-side settings.
     * This is <b>not</b> a replacement for {@link #equals(Object)}.
     * @param other Account object to compare
     * @return true if the two accounts differ in sync or server-side settings
     */
    public final boolean settingsDiffer(Account other) {
        // If the other object doesn't exist, they differ significantly.
        if (other == null) {
            return true;
        }
        // Check all the server-side settings, the user-side settings and the sync status.
        return ((this.syncStatus != other.syncStatus)
                || !Objects.equal(accountFromAddresses, other.accountFromAddresses)
                || color != other.color
                || (this.settings.hashCode() != other.settings.hashCode()));
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(name,
                senderName,
                accountManagerName,
                type,
                capabilities,
                providerVersion,
                uri,
                folderListUri,
                fullFolderListUri,
                allFolderListUri,
                searchUri,
                accountFromAddresses,
                expungeMessageUri,
                undoUri,
                settingsIntentUri,
                helpIntentUri,
                sendFeedbackIntentUri,
                reauthenticationIntentUri,
                syncStatus,
                composeIntentUri,
                mimeType,
                recentFolderListUri,
                color,
                defaultRecentFolderListUri,
                viewIntentProxyUri,
                accoutCookieQueryUri,
                updateSettingsUri,
                enableMessageTransforms,
                syncAuthority,
                quickResponseUri);
    }

    /**
     * Returns whether two Accounts match, as determined by their base URIs.
     * <p>For a deep object comparison, use {@link #equals(Object)}.
     *
     */
    public boolean matches(Account other) {
        return other != null && Objects.equal(uri, other.uri);
    }

    public List<ReplyFromAccount> getReplyFroms() {

        if (mReplyFroms == null) {
            mReplyFroms = Lists.newArrayList();

            // skip if sending is unsupported
            if (supportsCapability(AccountCapabilities.SENDING_UNAVAILABLE)) {
                return mReplyFroms;
            }

            // add the main account address
            // TODO: name is incorrect here, use senderName once FromAddressSpinner is fixed
            // b/11292541
            mReplyFroms.add(new ReplyFromAccount(this, uri, getEmailAddress(), name,
                    getEmailAddress(), false /* isDefault */, false /* isCustom */));

            if (!TextUtils.isEmpty(accountFromAddresses)) {
                try {
                    JSONArray accounts = new JSONArray(accountFromAddresses);

                    for (int i = 0, len = accounts.length(); i < len; i++) {
                        final ReplyFromAccount a = ReplyFromAccount.deserialize(this,
                                accounts.getJSONObject(i));
                        if (a != null) {
                            mReplyFroms.add(a);
                        }
                    }

                } catch (JSONException e) {
                    LogUtils.e(LOG_TAG, e, "Unable to parse accountFromAddresses. name=%s", name);
                }
            }
        }
        return mReplyFroms;
    }

    /**
     * @param fromAddress a raw email address, e.g. "user@domain.com"
     * @return if the address belongs to this Account (either as the main address or as a
     * custom-from)
     */
    public boolean ownsFromAddress(String fromAddress) {
        for (ReplyFromAccount replyFrom : getReplyFroms()) {
            if (TextUtils.equals(replyFrom.address, fromAddress)) {
                return true;
            }
        }

        return false;
    }

    public String getEmailAddress() {
        return accountManagerName;
    }

    /**
     * Returns the real name associated with the account, e.g. "John Doe" or null if no such name
     * has been configured
     * @return sender name
     */
    public String getSenderName() {
        return senderName;
    }

    @SuppressWarnings("hiding")
    public static final ClassLoaderCreator<Account> CREATOR = new ClassLoaderCreator<Account>() {
        @Override
        public Account createFromParcel(Parcel source, ClassLoader loader) {
            return new Account(source, loader);
        }

        @Override
        public Account createFromParcel(Parcel source) {
            return new Account(source, null);
        }

        @Override
        public Account[] newArray(int size) {
            return new Account[size];
        }
    };

    /**
     * Creates a {@link Map} where the column name is the key and the value is the value, which can
     * be used for populating a {@link MatrixCursor}.
     */
    public Map<String, Object> getValueMap() {
        // ImmutableMap.Builder does not allow null values
        final Map<String, Object> map = new HashMap<String, Object>();

        map.put(AccountColumns._ID, 0);
        map.put(AccountColumns.NAME, name);
        map.put(AccountColumns.SENDER_NAME, senderName);
        map.put(AccountColumns.TYPE, type);
        map.put(AccountColumns.ACCOUNT_MANAGER_NAME, accountManagerName);
        map.put(AccountColumns.PROVIDER_VERSION, providerVersion);
        map.put(AccountColumns.URI, uri);
        map.put(AccountColumns.CAPABILITIES, capabilities);
        map.put(AccountColumns.FOLDER_LIST_URI, folderListUri);
        map.put(AccountColumns.FULL_FOLDER_LIST_URI, fullFolderListUri);
        map.put(AccountColumns.ALL_FOLDER_LIST_URI, allFolderListUri);
        map.put(AccountColumns.SEARCH_URI, searchUri);
        map.put(AccountColumns.ACCOUNT_FROM_ADDRESSES, accountFromAddresses);
        map.put(AccountColumns.EXPUNGE_MESSAGE_URI, expungeMessageUri);
        map.put(AccountColumns.UNDO_URI, undoUri);
        map.put(AccountColumns.SETTINGS_INTENT_URI, settingsIntentUri);
        map.put(AccountColumns.HELP_INTENT_URI, helpIntentUri);
        map.put(AccountColumns.SEND_FEEDBACK_INTENT_URI, sendFeedbackIntentUri);
        map.put(AccountColumns.REAUTHENTICATION_INTENT_URI, reauthenticationIntentUri);
        map.put(AccountColumns.SYNC_STATUS, syncStatus);
        map.put(AccountColumns.COMPOSE_URI, composeIntentUri);
        map.put(AccountColumns.MIME_TYPE, mimeType);
        map.put(AccountColumns.RECENT_FOLDER_LIST_URI, recentFolderListUri);
        map.put(AccountColumns.DEFAULT_RECENT_FOLDER_LIST_URI, defaultRecentFolderListUri);
        map.put(AccountColumns.MANUAL_SYNC_URI, manualSyncUri);
        map.put(AccountColumns.VIEW_INTENT_PROXY_URI, viewIntentProxyUri);
        map.put(AccountColumns.ACCOUNT_COOKIE_QUERY_URI, accoutCookieQueryUri);
        map.put(AccountColumns.COLOR, color);
        map.put(AccountColumns.UPDATE_SETTINGS_URI, updateSettingsUri);
        map.put(AccountColumns.ENABLE_MESSAGE_TRANSFORMS, enableMessageTransforms);
        map.put(AccountColumns.SYNC_AUTHORITY, syncAuthority);
        map.put(AccountColumns.QUICK_RESPONSE_URI, quickResponseUri);
        settings.getValueMap(map);

        return map;
    }

    /**
     * Public object that knows how to construct Accounts given Cursors.
     */
    public final static CursorCreator<Account> FACTORY = new CursorCreator<Account>() {
        @Override
        public Account createFromCursor(Cursor c) {
            return new Account(c);
        }

        @Override
        public String toString() {
            return "Account CursorCreator";
        }
    };
}
