package com.android.exchange.adapter;

import android.content.ContentProviderOperation;
import android.content.ContentProviderOperation.Builder;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Entity;
import android.content.Entity.NamedContentValues;
import android.content.EntityIterator;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.net.Uri;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Event;
import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
import android.provider.ContactsContract.CommonDataKinds.Im;
import android.provider.ContactsContract.CommonDataKinds.Nickname;
import android.provider.ContactsContract.CommonDataKinds.Note;
import android.provider.ContactsContract.CommonDataKinds.Organization;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.Relation;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.CommonDataKinds.Website;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.SyncState;
import android.provider.SyncStateContract;
import android.text.util.Rfc822Token;
import android.text.util.Rfc822Tokenizer;
import android.util.Base64;

import com.android.emailcommon.provider.Account;
import com.android.emailcommon.provider.Mailbox;
import com.android.emailcommon.utility.Utility;
import com.android.exchange.Eas;
import com.android.exchange.eas.EasSyncCollectionTypeBase;
import com.android.exchange.eas.EasSyncContacts;
import com.android.exchange.utility.CalendarUtilities;
import com.android.mail.utils.LogUtils;

import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.TimeZone;

public class ContactsSyncParser extends AbstractSyncParser {
    private static final String TAG = Eas.LOG_TAG;

    private static final String SERVER_ID_SELECTION = RawContacts.SOURCE_ID + "=?";
    private static final String CLIENT_ID_SELECTION = RawContacts.SYNC1 + "=?";
    private static final String[] ID_PROJECTION = new String[] {RawContacts._ID};

    private static final ArrayList<NamedContentValues> EMPTY_ARRAY_NAMEDCONTENTVALUES
        = new ArrayList<NamedContentValues>();

    private static final String FOUND_DATA_ROW = "com.android.exchange.FOUND_ROW";

    private static final int MAX_IM_ROWS = 3;
    private static final int MAX_EMAIL_ROWS = 3;
    private static final int MAX_PHONE_ROWS = 2;
    private static final String COMMON_DATA_ROW = Im.DATA;  // Could have been Email.DATA, etc.
    private static final String COMMON_TYPE_ROW = Phone.TYPE; // Could have been any typed row

    String[] mBindArgument = new String[1];
    ContactOperations ops = new ContactOperations();
    private final android.accounts.Account mAccountManagerAccount;
    private final Uri mAccountUri;
    private boolean mGroupsUsed = false;

    public ContactsSyncParser(final Context context, final ContentResolver resolver,
            final InputStream in, final Mailbox mailbox, final Account account,
            final android.accounts.Account accountManagerAccount) throws IOException {
        super(context, resolver, in, mailbox, account);
        mAccountManagerAccount = accountManagerAccount;
        mAccountUri = uriWithAccountAndIsSyncAdapter(RawContacts.CONTENT_URI,
                mAccount.mEmailAddress);
    }

    public boolean isGroupsUsed() {
        return mGroupsUsed;
    }

    public void addData(String serverId, ContactOperations ops, Entity entity)
            throws IOException {
        String prefix = null;
        String firstName = null;
        String lastName = null;
        String middleName = null;
        String suffix = null;
        String companyName = null;
        String yomiFirstName = null;
        String yomiLastName = null;
        String yomiCompanyName = null;
        String title = null;
        String department = null;
        String officeLocation = null;
        Address home = new Address();
        Address work = new Address();
        Address other = new Address();
        EasBusiness business = new EasBusiness();
        EasPersonal personal = new EasPersonal();
        ArrayList<String> children = new ArrayList<String>();
        ArrayList<UntypedRow> emails = new ArrayList<UntypedRow>();
        ArrayList<UntypedRow> ims = new ArrayList<UntypedRow>();
        ArrayList<UntypedRow> homePhones = new ArrayList<UntypedRow>();
        ArrayList<UntypedRow> workPhones = new ArrayList<UntypedRow>();
        if (entity == null) {
            ops.newContact(serverId, mAccount.mEmailAddress);
        }

        while (nextTag(Tags.SYNC_APPLICATION_DATA) != END) {
            switch (tag) {
                case Tags.CONTACTS_FIRST_NAME:
                    firstName = getValue();
                    break;
                case Tags.CONTACTS_LAST_NAME:
                    lastName = getValue();
                    break;
                case Tags.CONTACTS_MIDDLE_NAME:
                    middleName = getValue();
                    break;
                case Tags.CONTACTS_SUFFIX:
                    suffix = getValue();
                    break;
                case Tags.CONTACTS_COMPANY_NAME:
                    companyName = getValue();
                    break;
                case Tags.CONTACTS_JOB_TITLE:
                    title = getValue();
                    break;
                case Tags.CONTACTS_EMAIL1_ADDRESS:
                case Tags.CONTACTS_EMAIL2_ADDRESS:
                case Tags.CONTACTS_EMAIL3_ADDRESS:
                    emails.add(new EmailRow(getValue()));
                    break;
                case Tags.CONTACTS_BUSINESS2_TELEPHONE_NUMBER:
                case Tags.CONTACTS_BUSINESS_TELEPHONE_NUMBER:
                    workPhones.add(new PhoneRow(getValue(), Phone.TYPE_WORK));
                    break;
                case Tags.CONTACTS2_MMS:
                    ops.addPhone(entity, Phone.TYPE_MMS, getValue());
                    break;
                case Tags.CONTACTS_BUSINESS_FAX_NUMBER:
                    ops.addPhone(entity, Phone.TYPE_FAX_WORK, getValue());
                    break;
                case Tags.CONTACTS2_COMPANY_MAIN_PHONE:
                    ops.addPhone(entity, Phone.TYPE_COMPANY_MAIN, getValue());
                    break;
                case Tags.CONTACTS_HOME_FAX_NUMBER:
                    ops.addPhone(entity, Phone.TYPE_FAX_HOME, getValue());
                    break;
                case Tags.CONTACTS_HOME_TELEPHONE_NUMBER:
                case Tags.CONTACTS_HOME2_TELEPHONE_NUMBER:
                    homePhones.add(new PhoneRow(getValue(), Phone.TYPE_HOME));
                    break;
                case Tags.CONTACTS_MOBILE_TELEPHONE_NUMBER:
                    ops.addPhone(entity, Phone.TYPE_MOBILE, getValue());
                    break;
                case Tags.CONTACTS_CAR_TELEPHONE_NUMBER:
                    ops.addPhone(entity, Phone.TYPE_CAR, getValue());
                    break;
                case Tags.CONTACTS_RADIO_TELEPHONE_NUMBER:
                    ops.addPhone(entity, Phone.TYPE_RADIO, getValue());
                    break;
                case Tags.CONTACTS_PAGER_NUMBER:
                    ops.addPhone(entity, Phone.TYPE_PAGER, getValue());
                    break;
                case Tags.CONTACTS_ASSISTANT_TELEPHONE_NUMBER:
                    ops.addPhone(entity, Phone.TYPE_ASSISTANT, getValue());
                    break;
                case Tags.CONTACTS2_IM_ADDRESS:
                case Tags.CONTACTS2_IM_ADDRESS_2:
                case Tags.CONTACTS2_IM_ADDRESS_3:
                    ims.add(new ImRow(getValue()));
                    break;
                case Tags.CONTACTS_BUSINESS_ADDRESS_CITY:
                    work.city = getValue();
                    break;
                case Tags.CONTACTS_BUSINESS_ADDRESS_COUNTRY:
                    work.country = getValue();
                    break;
                case Tags.CONTACTS_BUSINESS_ADDRESS_POSTAL_CODE:
                    work.code = getValue();
                    break;
                case Tags.CONTACTS_BUSINESS_ADDRESS_STATE:
                    work.state = getValue();
                    break;
                case Tags.CONTACTS_BUSINESS_ADDRESS_STREET:
                    work.street = getValue();
                    break;
                case Tags.CONTACTS_HOME_ADDRESS_CITY:
                    home.city = getValue();
                    break;
                case Tags.CONTACTS_HOME_ADDRESS_COUNTRY:
                    home.country = getValue();
                    break;
                case Tags.CONTACTS_HOME_ADDRESS_POSTAL_CODE:
                    home.code = getValue();
                    break;
                case Tags.CONTACTS_HOME_ADDRESS_STATE:
                    home.state = getValue();
                    break;
                case Tags.CONTACTS_HOME_ADDRESS_STREET:
                    home.street = getValue();
                    break;
                case Tags.CONTACTS_OTHER_ADDRESS_CITY:
                    other.city = getValue();
                    break;
                case Tags.CONTACTS_OTHER_ADDRESS_COUNTRY:
                    other.country = getValue();
                    break;
                case Tags.CONTACTS_OTHER_ADDRESS_POSTAL_CODE:
                    other.code = getValue();
                    break;
                case Tags.CONTACTS_OTHER_ADDRESS_STATE:
                    other.state = getValue();
                    break;
                case Tags.CONTACTS_OTHER_ADDRESS_STREET:
                    other.street = getValue();
                    break;

                case Tags.CONTACTS_CHILDREN:
                    childrenParser(children);
                    break;

                case Tags.CONTACTS_YOMI_COMPANY_NAME:
                    yomiCompanyName = getValue();
                    break;
                case Tags.CONTACTS_YOMI_FIRST_NAME:
                    yomiFirstName = getValue();
                    break;
                case Tags.CONTACTS_YOMI_LAST_NAME:
                    yomiLastName = getValue();
                    break;

                case Tags.CONTACTS2_NICKNAME:
                    ops.addNickname(entity, getValue());
                    break;

                case Tags.CONTACTS_ASSISTANT_NAME:
                    ops.addRelation(entity, Relation.TYPE_ASSISTANT, getValue());
                    break;
                case Tags.CONTACTS2_MANAGER_NAME:
                    ops.addRelation(entity, Relation.TYPE_MANAGER, getValue());
                    break;
                case Tags.CONTACTS_SPOUSE:
                    ops.addRelation(entity, Relation.TYPE_SPOUSE, getValue());
                    break;
                case Tags.CONTACTS_DEPARTMENT:
                    department = getValue();
                    break;
                case Tags.CONTACTS_TITLE:
                    prefix = getValue();
                    break;

                // EAS Business
                case Tags.CONTACTS_OFFICE_LOCATION:
                    officeLocation = getValue();
                    break;
                case Tags.CONTACTS2_CUSTOMER_ID:
                    business.customerId = getValue();
                    break;
                case Tags.CONTACTS2_GOVERNMENT_ID:
                    business.governmentId = getValue();
                    break;
                case Tags.CONTACTS2_ACCOUNT_NAME:
                    business.accountName = getValue();
                    break;

                // EAS Personal
                case Tags.CONTACTS_ANNIVERSARY:
                    personal.anniversary = getValue();
                    break;
                case Tags.CONTACTS_FILE_AS:
                    personal.fileAs = getValue();
                    break;
                case Tags.CONTACTS_BIRTHDAY:
                    ops.addBirthday(entity, getValue());
                    break;
                case Tags.CONTACTS_WEBPAGE:
                    ops.addWebpage(entity, getValue());
                    break;

                case Tags.CONTACTS_PICTURE:
                    ops.addPhoto(entity, getValue());
                    break;

                case Tags.BASE_BODY:
                    ops.addNote(entity, bodyParser());
                    break;
                case Tags.CONTACTS_BODY:
                    ops.addNote(entity, getValue());
                    break;

                case Tags.CONTACTS_CATEGORIES:
                    mGroupsUsed = true;
                    categoriesParser(ops, entity);
                    break;

                default:
                    skipTag();
            }
        }

        ops.addName(entity, prefix, firstName, lastName, middleName, suffix,
                yomiFirstName, yomiLastName);
        ops.addBusiness(entity, business);
        ops.addPersonal(entity, personal);

        ops.addUntyped(entity, emails, Email.CONTENT_ITEM_TYPE, -1, MAX_EMAIL_ROWS);
        ops.addUntyped(entity, ims, Im.CONTENT_ITEM_TYPE, -1, MAX_IM_ROWS);
        ops.addUntyped(entity, homePhones, Phone.CONTENT_ITEM_TYPE, Phone.TYPE_HOME,
                MAX_PHONE_ROWS);
        ops.addUntyped(entity, workPhones, Phone.CONTENT_ITEM_TYPE, Phone.TYPE_WORK,
                MAX_PHONE_ROWS);

        if (!children.isEmpty()) {
            ops.addChildren(entity, children);
        }

        if (work.hasData()) {
            ops.addPostal(entity, StructuredPostal.TYPE_WORK, work.street, work.city,
                    work.state, work.country, work.code);
        }
        if (home.hasData()) {
            ops.addPostal(entity, StructuredPostal.TYPE_HOME, home.street, home.city,
                    home.state, home.country, home.code);
        }
        if (other.hasData()) {
            ops.addPostal(entity, StructuredPostal.TYPE_OTHER, other.street, other.city,
                    other.state, other.country, other.code);
        }

        if (companyName != null) {
            ops.addOrganization(entity, Organization.TYPE_WORK, companyName, title, department,
                    yomiCompanyName, officeLocation);
        }

        if (entity != null) {
            // We've been removing rows from the list as they've been found in the xml
            // Any that are left must have been deleted on the server
            ArrayList<NamedContentValues> ncvList = entity.getSubValues();
            for (NamedContentValues ncv: ncvList) {
                // These rows need to be deleted...
                Uri u = dataUriFromNamedContentValues(ncv);
                ops.add(ContentProviderOperation.newDelete(addCallerIsSyncAdapterParameter(u))
                        .build());
            }
        }
    }

    private void categoriesParser(ContactOperations ops, Entity entity) throws IOException {
        while (nextTag(Tags.CONTACTS_CATEGORIES) != END) {
            switch (tag) {
                case Tags.CONTACTS_CATEGORY:
                    ops.addGroup(entity, getValue());
                    break;
                default:
                    skipTag();
            }
        }
    }

    private void childrenParser(ArrayList<String> children) throws IOException {
        while (nextTag(Tags.CONTACTS_CHILDREN) != END) {
            switch (tag) {
                case Tags.CONTACTS_CHILD:
                    if (children.size() < EasChildren.MAX_CHILDREN) {
                        children.add(getValue());
                    }
                    break;
                default:
                    skipTag();
            }
        }
    }

    private String bodyParser() throws IOException {
        String body = null;
        while (nextTag(Tags.BASE_BODY) != END) {
            switch (tag) {
                case Tags.BASE_DATA:
                    body = getValue();
                    break;
                default:
                    skipTag();
            }
        }
        return body;
    }

    public void addParser(ContactOperations ops) throws IOException {
        String serverId = null;
        while (nextTag(Tags.SYNC_ADD) != END) {
            switch (tag) {
                case Tags.SYNC_SERVER_ID: // same as
                    serverId = getValue();
                    break;
                case Tags.SYNC_APPLICATION_DATA:
                    addData(serverId, ops, null);
                    break;
                default:
                    skipTag();
            }
        }
    }

    private Cursor getServerIdCursor(String serverId) {
        mBindArgument[0] = serverId;
        return mContentResolver.query(mAccountUri, ID_PROJECTION, SERVER_ID_SELECTION,
                mBindArgument, null);
    }

    private Cursor getClientIdCursor(String clientId) {
        mBindArgument[0] = clientId;
        return mContentResolver.query(mAccountUri, ID_PROJECTION, CLIENT_ID_SELECTION,
                mBindArgument, null);
    }

    public void deleteParser(ContactOperations ops) throws IOException {
        while (nextTag(Tags.SYNC_DELETE) != END) {
            switch (tag) {
                case Tags.SYNC_SERVER_ID:
                    String serverId = getValue();
                    // Find the message in this mailbox with the given serverId
                    Cursor c = getServerIdCursor(serverId);
                    try {
                        if (c.moveToFirst()) {
                            userLog("Deleting ", serverId);
                            ops.delete(c.getLong(0));
                        }
                    } finally {
                        c.close();
                    }
                    break;
                default:
                    skipTag();
            }
        }
    }

    class ServerChange {
        long id;
        boolean read;

        ServerChange(long _id, boolean _read) {
            id = _id;
            read = _read;
        }
    }

    /**
     * Changes are handled row by row, and only changed/new rows are acted upon
     * @param ops the array of pending ContactProviderOperations.
     * @throws IOException
     */
    public void changeParser(ContactOperations ops) throws IOException {
        String serverId = null;
        Entity entity = null;
        while (nextTag(Tags.SYNC_CHANGE) != END) {
            switch (tag) {
                case Tags.SYNC_SERVER_ID:
                    serverId = getValue();
                    Cursor c = getServerIdCursor(serverId);
                    try {
                        if (c.moveToFirst()) {
                            // TODO Handle deleted individual rows...
                            Uri uri = ContentUris.withAppendedId(
                                    RawContacts.CONTENT_URI, c.getLong(0));
                            uri = Uri.withAppendedPath(
                                    uri, RawContacts.Entity.CONTENT_DIRECTORY);
                            EntityIterator entityIterator = RawContacts.newEntityIterator(
                                mContentResolver.query(uri, null, null, null, null));
                            if (entityIterator.hasNext()) {
                                entity = entityIterator.next();
                            }
                            userLog("Changing contact ", serverId);
                        }
                    } finally {
                        c.close();
                    }
                    break;
                case Tags.SYNC_APPLICATION_DATA:
                    addData(serverId, ops, entity);
                    break;
                default:
                    skipTag();
            }
        }
    }

    @Override
    public void commandsParser() throws IOException {
        while (nextTag(Tags.SYNC_COMMANDS) != END) {
            if (tag == Tags.SYNC_ADD) {
                addParser(ops);
            } else if (tag == Tags.SYNC_DELETE) {
                deleteParser(ops);
            } else if (tag == Tags.SYNC_CHANGE) {
                changeParser(ops);
            } else
                skipTag();
        }
    }

    @Override
    public void commit() throws IOException {
       // Save the syncKey here, using the Helper provider by Contacts provider
        userLog("Contacts SyncKey saved as: ", mMailbox.mSyncKey);
        ops.add(SyncStateContract.Helpers.newSetOperation(SyncState.CONTENT_URI,
                mAccountManagerAccount, mMailbox.mSyncKey.getBytes()));

        // Execute these all at once...
        ops.execute(mContext);

        if (ops.mResults != null) {
            ContentValues cv = new ContentValues();
            cv.put(RawContacts.DIRTY, 0);
            for (int i = 0; i < ops.mContactIndexCount; i++) {
                int index = ops.mContactIndexArray[i];
                Uri u = ops.mResults[index].uri;
                if (u != null) {
                    String idString = u.getLastPathSegment();
                    mContentResolver.update(
                            addCallerIsSyncAdapterParameter(RawContacts.CONTENT_URI), cv,
                            RawContacts._ID + "=" + idString, null);
                }
            }
        }
    }

    public void addResponsesParser() throws IOException {
        String serverId = null;
        String clientId = null;
        ContentValues cv = new ContentValues();
        while (nextTag(Tags.SYNC_ADD) != END) {
            switch (tag) {
                case Tags.SYNC_SERVER_ID:
                    serverId = getValue();
                    break;
                case Tags.SYNC_CLIENT_ID:
                    clientId = getValue();
                    break;
                case Tags.SYNC_STATUS:
                    getValue();
                    break;
                default:
                    skipTag();
            }
        }

        // This is theoretically impossible, but...
        if (clientId == null || serverId == null) return;

        Cursor c = getClientIdCursor(clientId);
        try {
            if (c.moveToFirst()) {
                cv.put(RawContacts.SOURCE_ID, serverId);
                cv.put(RawContacts.DIRTY, 0);
                ops.add(ContentProviderOperation.newUpdate(
                        ContentUris.withAppendedId(
                                addCallerIsSyncAdapterParameter(RawContacts.CONTENT_URI),
                                c.getLong(0)))
                        .withValues(cv)
                        .build());
                userLog("New contact " + clientId + " was given serverId: " + serverId);
            }
        } finally {
            c.close();
        }
    }

    public void changeResponsesParser() throws IOException {
        String serverId = null;
        String status = null;
        while (nextTag(Tags.SYNC_CHANGE) != END) {
            switch (tag) {
                case Tags.SYNC_SERVER_ID:
                    serverId = getValue();
                    break;
                case Tags.SYNC_STATUS:
                    status = getValue();
                    break;
                default:
                    skipTag();
            }
        }
        if (serverId != null && status != null) {
            userLog("Changed contact " + serverId + " failed with status: " + status);
        }
    }


    @Override
    public void responsesParser() throws IOException {
        // Handle server responses here (for Add and Change)
        while (nextTag(Tags.SYNC_RESPONSES) != END) {
            if (tag == Tags.SYNC_ADD) {
                addResponsesParser();
            } else if (tag == Tags.SYNC_CHANGE) {
                changeResponsesParser();
            } else
                skipTag();
        }
    }

    private static Uri uriWithAccountAndIsSyncAdapter(final Uri uri, final String emailAddress) {
        return uri.buildUpon()
            .appendQueryParameter(RawContacts.ACCOUNT_NAME, emailAddress)
            .appendQueryParameter(RawContacts.ACCOUNT_TYPE, Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE)
            .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
            .build();
    }

    static Uri addCallerIsSyncAdapterParameter(Uri uri) {
        return uri.buildUpon()
                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
                .build();
    }

    /**
     * Generate the uri for the data row associated with this NamedContentValues object
     * @param ncv the NamedContentValues object
     * @return a uri that can be used to refer to this row
     */
    public static Uri dataUriFromNamedContentValues(NamedContentValues ncv) {
        long id = ncv.values.getAsLong(RawContacts._ID);
        Uri dataUri = ContentUris.withAppendedId(ncv.uri, id);
        return dataUri;
    }

    public static final class EasChildren {
        private EasChildren() {}

        /** MIME type used when storing this in data table. */
        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/eas_children";
        public static final int MAX_CHILDREN = 8;
        public static final String[] ROWS =
            new String[] {"data2", "data3", "data4", "data5", "data6", "data7", "data8", "data9"};
    }

    public static final class EasPersonal {
        String anniversary;
        String fileAs;

            /** MIME type used when storing this in data table. */
        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/eas_personal";
        public static final String ANNIVERSARY = "data2";
        public static final String FILE_AS = "data4";

        boolean hasData() {
            return anniversary != null || fileAs != null;
        }
    }

    public static final class EasBusiness {
        String customerId;
        String governmentId;
        String accountName;

        /** MIME type used when storing this in data table. */
        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/eas_business";
        public static final String CUSTOMER_ID = "data6";
        public static final String GOVERNMENT_ID = "data7";
        public static final String ACCOUNT_NAME = "data8";

        boolean hasData() {
            return customerId != null || governmentId != null || accountName != null;
        }
    }

    public static final class Address {
        String city;
        String country;
        String code;
        String street;
        String state;

        boolean hasData() {
            return city != null || country != null || code != null || state != null
                || street != null;
        }
    }

    interface UntypedRow {
        public void addValues(RowBuilder builder);
        public boolean isSameAs(int type, String value);
    }

    static class EmailRow implements UntypedRow {
        String email;
        String displayName;

        public EmailRow(String _email) {
            Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(_email);
            // Can't happen, but belt & suspenders
            if (tokens.length == 0) {
                email = "";
                displayName = "";
            } else {
                Rfc822Token token = tokens[0];
                email = token.getAddress();
                displayName = token.getName();
            }
        }

        @Override
        public void addValues(RowBuilder builder) {
            builder.withValue(Email.DATA, email);
            builder.withValue(Email.DISPLAY_NAME, displayName);
        }

        @Override
        public boolean isSameAs(int type, String value) {
            return email.equalsIgnoreCase(value);
        }
    }

    static class ImRow implements UntypedRow {
        String im;

        public ImRow(String _im) {
            im = _im;
        }

        @Override
        public void addValues(RowBuilder builder) {
            builder.withValue(Im.DATA, im);
        }

        @Override
        public boolean isSameAs(int type, String value) {
            return im.equalsIgnoreCase(value);
        }
    }

    static class PhoneRow implements UntypedRow {
        String phone;
        int type;

        public PhoneRow(String _phone, int _type) {
            phone = _phone;
            type = _type;
        }

        @Override
        public void addValues(RowBuilder builder) {
            builder.withValue(Im.DATA, phone);
            builder.withValue(Phone.TYPE, type);
        }

        @Override
        public boolean isSameAs(int _type, String value) {
            return type == _type && phone.equalsIgnoreCase(value);
        }
    }

    /**
     * RowBuilder is a wrapper for the Builder class that is used to create/update rows for a
     * ContentProvider.  It has, in addition to the Builder, ContentValues which, if present,
     * represent the current values of that row, that can be compared against current values to
     * see whether an update is even necessary.  The methods on SmartBuilder are delegated to
     * the Builder.
     */
    private static class RowBuilder {
        Builder builder;
        ContentValues cv;

        public RowBuilder(Builder _builder) {
            builder = _builder;
        }

        public RowBuilder(Builder _builder, NamedContentValues _ncv) {
            builder = _builder;
            cv = _ncv.values;
        }

        RowBuilder withValueBackReference(String key, int previousResult) {
            builder.withValueBackReference(key, previousResult);
            return this;
        }

        ContentProviderOperation build() {
            return builder.build();
        }

        RowBuilder withValue(String key, Object value) {
            builder.withValue(key, value);
            return this;
        }
    }
    public static class ContactOperations extends ArrayList<ContentProviderOperation> {
        private static final long serialVersionUID = 1L;
        private int mCount = 0;
        private int mContactBackValue = mCount;
        // Make an array big enough for the max possible window size.
        private final int[] mContactIndexArray = new int[EasSyncCollectionTypeBase.MAX_WINDOW_SIZE];
        private int mContactIndexCount = 0;
        private ContentProviderResult[] mResults = null;

        @Override
        public boolean add(ContentProviderOperation op) {
            super.add(op);
            mCount++;
            return true;
        }

        public void newContact(final String serverId, final String emailAddress) {
            Builder builder = ContentProviderOperation.newInsert(
                    uriWithAccountAndIsSyncAdapter(RawContacts.CONTENT_URI, emailAddress));
            ContentValues values = new ContentValues();
            values.put(RawContacts.SOURCE_ID, serverId);
            builder.withValues(values);
            mContactBackValue = mCount;
            mContactIndexArray[mContactIndexCount++] = mCount;
            add(builder.build());
        }

        public void delete(long id) {
            add(ContentProviderOperation
                    .newDelete(ContentUris.withAppendedId(RawContacts.CONTENT_URI, id)
                            .buildUpon()
                            .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
                            .build())
                    .build());
        }

        public void execute(final Context context) {
            try {
                if (!isEmpty()) {
                    mResults = context.getContentResolver().applyBatch(
                            ContactsContract.AUTHORITY, this);
                }
            } catch (RemoteException e) {
                // There is nothing sensible to be done here
                LogUtils.e(TAG, "problem inserting contact during server update", e);
            } catch (OperationApplicationException e) {
                // There is nothing sensible to be done here
                LogUtils.e(TAG, "problem inserting contact during server update", e);
            }
        }

        /**
         * Given the list of NamedContentValues for an entity, a mime type, and a subtype,
         * tries to find a match, returning it
         * @param list the list of NCV's from the contact entity
         * @param contentItemType the mime type we're looking for
         * @param type the subtype (e.g. HOME, WORK, etc.)
         * @return the matching NCV or null if not found
         */
        private static NamedContentValues findTypedData(ArrayList<NamedContentValues> list,
                String contentItemType, int type, String stringType) {
            NamedContentValues result = null;

            // Loop through the ncv's, looking for an existing row
            for (NamedContentValues namedContentValues: list) {
                Uri uri = namedContentValues.uri;
                ContentValues cv = namedContentValues.values;
                if (Data.CONTENT_URI.equals(uri)) {
                    String mimeType = cv.getAsString(Data.MIMETYPE);
                    if (mimeType.equals(contentItemType)) {
                        if (stringType != null) {
                            if (cv.getAsString(GroupMembership.GROUP_ROW_ID).equals(stringType)) {
                                result = namedContentValues;
                            }
                        // Note Email.TYPE could be ANY type column; they are all defined in
                        // the private CommonColumns class in ContactsContract
                        // We'll accept either type < 0 (don't care), cv doesn't have a type,
                        // or the types are equal
                        } else if (type < 0 || !cv.containsKey(Email.TYPE) ||
                                cv.getAsInteger(Email.TYPE) == type) {
                            result = namedContentValues;
                        }
                    }
                }
            }

            // If we've found an existing data row, we'll delete it.  Any rows left at the
            // end should be deleted...
            if (result != null) {
                list.remove(result);
            }

            // Return the row found (or null)
            return result;
        }

        /**
         * Given the list of NamedContentValues for an entity and a mime type
         * gather all of the matching NCV's, returning them
         * @param list the list of NCV's from the contact entity
         * @param contentItemType the mime type we're looking for
         * @param type the subtype (e.g. HOME, WORK, etc.)
         * @return the matching NCVs
         */
        private static ArrayList<NamedContentValues> findUntypedData(
                ArrayList<NamedContentValues> list, int type, String contentItemType) {
            ArrayList<NamedContentValues> result = new ArrayList<NamedContentValues>();

            // Loop through the ncv's, looking for an existing row
            for (NamedContentValues namedContentValues: list) {
                Uri uri = namedContentValues.uri;
                ContentValues cv = namedContentValues.values;
                if (Data.CONTENT_URI.equals(uri)) {
                    String mimeType = cv.getAsString(Data.MIMETYPE);
                    if (mimeType.equals(contentItemType)) {
                        if (type != -1) {
                            int subtype = cv.getAsInteger(Phone.TYPE);
                            if (type != subtype) {
                                continue;
                            }
                        }
                        result.add(namedContentValues);
                    }
                }
            }

            // If we've found an existing data row, we'll delete it.  Any rows left at the
            // end should be deleted...
            for (NamedContentValues values : result) {
                list.remove(values);
            }

            // Return the row found (or null)
            return result;
        }

        /**
         * Create a wrapper for a builder (insert or update) that also includes the NCV for
         * an existing row of this type.   If the SmartBuilder's cv field is not null, then
         * it represents the current (old) values of this field.  The caller can then check
         * whether the field is now different and needs to be updated; if it's not different,
         * the caller will simply return and not generate a new CPO.  Otherwise, the builder
         * should have its content values set, and the built CPO should be added to the
         * ContactOperations list.
         *
         * @param entity the contact entity (or null if this is a new contact)
         * @param mimeType the mime type of this row
         * @param type the subtype of this row
         * @param stringType for groups, the name of the group (type will be ignored), or null
         * @return the created SmartBuilder
         */
        public RowBuilder createBuilder(Entity entity, String mimeType, int type,
                String stringType) {
            RowBuilder builder = null;

            if (entity != null) {
                NamedContentValues ncv =
                    findTypedData(entity.getSubValues(), mimeType, type, stringType);
                if (ncv != null) {
                    builder = new RowBuilder(
                            ContentProviderOperation
                                .newUpdate(addCallerIsSyncAdapterParameter(
                                    dataUriFromNamedContentValues(ncv))),
                            ncv);
                }
            }

            if (builder == null) {
                builder = newRowBuilder(entity, mimeType);
            }

            // Return the appropriate builder (insert or update)
            // Caller will fill in the appropriate values; 4 MIMETYPE is already set
            return builder;
        }

        private RowBuilder typedRowBuilder(Entity entity, String mimeType, int type) {
            return createBuilder(entity, mimeType, type, null);
        }

        private RowBuilder untypedRowBuilder(Entity entity, String mimeType) {
            return createBuilder(entity, mimeType, -1, null);
        }

        private RowBuilder newRowBuilder(Entity entity, String mimeType) {
            // This is a new row; first get the contactId
            // If the Contact is new, use the saved back value; otherwise the value in the entity
            int contactId = mContactBackValue;
            if (entity != null) {
                contactId = entity.getEntityValues().getAsInteger(RawContacts._ID);
            }

            // Create an insert operation with the proper contactId reference
            RowBuilder builder =
                new RowBuilder(ContentProviderOperation.newInsert(
                        addCallerIsSyncAdapterParameter(Data.CONTENT_URI)));
            if (entity == null) {
                builder.withValueBackReference(Data.RAW_CONTACT_ID, contactId);
            } else {
                builder.withValue(Data.RAW_CONTACT_ID, contactId);
            }

            // Set the mime type of the row
            builder.withValue(Data.MIMETYPE, mimeType);
            return builder;
        }

        /**
         * Compare a column in a ContentValues with an (old) value, and see if they are the
         * same.  For this purpose, null and an empty string are considered the same.
         * @param cv a ContentValues object, from a NamedContentValues
         * @param column a column that might be in the ContentValues
         * @param oldValue an old value (or null) to check against
         * @return whether the column's value in the ContentValues matches oldValue
         */
        private static boolean cvCompareString(ContentValues cv, String column, String oldValue) {
            if (cv.containsKey(column)) {
                if (oldValue != null && cv.getAsString(column).equals(oldValue)) {
                    return true;
                }
            } else if (oldValue == null || oldValue.length() == 0) {
                return true;
            }
            return false;
        }

        public void addChildren(Entity entity, ArrayList<String> children) {
            RowBuilder builder = untypedRowBuilder(entity, EasChildren.CONTENT_ITEM_TYPE);
            int i = 0;
            for (String child: children) {
                builder.withValue(EasChildren.ROWS[i++], child);
            }
            add(builder.build());
        }

        public void addGroup(Entity entity, String group) {
            RowBuilder builder =
                createBuilder(entity, GroupMembership.CONTENT_ITEM_TYPE, -1, group);
            builder.withValue(GroupMembership.GROUP_SOURCE_ID, group);
            add(builder.build());
        }

        public void addBirthday(Entity entity, String birthday) {
            RowBuilder builder =
                    typedRowBuilder(entity, Event.CONTENT_ITEM_TYPE, Event.TYPE_BIRTHDAY);
            ContentValues cv = builder.cv;
            if (cv != null && cvCompareString(cv, Event.START_DATE, birthday)) {
                return;
            }
            // TODO: Store the date in the format expected by EAS servers.
            final long millis;
            try {
                millis = Utility.parseEmailDateTimeToMillis(birthday);
            } catch (ParseException e) {
                LogUtils.w(TAG, "Parse error for birthday date field.", e);
                return;
            }
            GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
            cal.setTimeInMillis(millis);
            if (cal.get(GregorianCalendar.HOUR_OF_DAY) >= 12) {
                cal.add(GregorianCalendar.DATE, 1);
            }
            String realBirthday = CalendarUtilities.calendarToBirthdayString(cal);
            builder.withValue(Event.START_DATE, realBirthday);
            builder.withValue(Event.TYPE, Event.TYPE_BIRTHDAY);
            add(builder.build());
        }

        public void addName(Entity entity, String prefix, String givenName, String familyName,
                String middleName, String suffix, String yomiFirstName, String yomiLastName) {
            RowBuilder builder = untypedRowBuilder(entity, StructuredName.CONTENT_ITEM_TYPE);
            ContentValues cv = builder.cv;
            if (cv != null && cvCompareString(cv, StructuredName.GIVEN_NAME, givenName) &&
                    cvCompareString(cv, StructuredName.FAMILY_NAME, familyName) &&
                    cvCompareString(cv, StructuredName.MIDDLE_NAME, middleName) &&
                    cvCompareString(cv, StructuredName.PREFIX, prefix) &&
                    cvCompareString(cv, StructuredName.PHONETIC_GIVEN_NAME, yomiFirstName) &&
                    cvCompareString(cv, StructuredName.PHONETIC_FAMILY_NAME, yomiLastName) &&
                    cvCompareString(cv, StructuredName.SUFFIX, suffix)) {
                return;
            }
            builder.withValue(StructuredName.GIVEN_NAME, givenName);
            builder.withValue(StructuredName.FAMILY_NAME, familyName);
            builder.withValue(StructuredName.MIDDLE_NAME, middleName);
            builder.withValue(StructuredName.SUFFIX, suffix);
            builder.withValue(StructuredName.PHONETIC_GIVEN_NAME, yomiFirstName);
            builder.withValue(StructuredName.PHONETIC_FAMILY_NAME, yomiLastName);
            builder.withValue(StructuredName.PREFIX, prefix);
            add(builder.build());
        }

        public void addPersonal(Entity entity, EasPersonal personal) {
            RowBuilder builder = untypedRowBuilder(entity, EasPersonal.CONTENT_ITEM_TYPE);
            ContentValues cv = builder.cv;
            if (cv != null && cvCompareString(cv, EasPersonal.ANNIVERSARY, personal.anniversary) &&
                    cvCompareString(cv, EasPersonal.FILE_AS , personal.fileAs)) {
                return;
            }
            if (!personal.hasData()) {
                return;
            }
            builder.withValue(EasPersonal.FILE_AS, personal.fileAs);
            builder.withValue(EasPersonal.ANNIVERSARY, personal.anniversary);
            add(builder.build());
        }

        public void addBusiness(Entity entity, EasBusiness business) {
            RowBuilder builder = untypedRowBuilder(entity, EasBusiness.CONTENT_ITEM_TYPE);
            ContentValues cv = builder.cv;
            if (cv != null && cvCompareString(cv, EasBusiness.ACCOUNT_NAME, business.accountName) &&
                    cvCompareString(cv, EasBusiness.CUSTOMER_ID, business.customerId) &&
                    cvCompareString(cv, EasBusiness.GOVERNMENT_ID, business.governmentId)) {
                return;
            }
            if (!business.hasData()) {
                return;
            }
            builder.withValue(EasBusiness.ACCOUNT_NAME, business.accountName);
            builder.withValue(EasBusiness.CUSTOMER_ID, business.customerId);
            builder.withValue(EasBusiness.GOVERNMENT_ID, business.governmentId);
            add(builder.build());
        }

        public void addPhoto(Entity entity, String photo) {
            RowBuilder builder = untypedRowBuilder(entity, Photo.CONTENT_ITEM_TYPE);
            // We're always going to add this; it's not worth trying to figure out whether the
            // picture is the same as the one stored.
            byte[] pic = Base64.decode(photo, Base64.DEFAULT);
            builder.withValue(Photo.PHOTO, pic);
            add(builder.build());
        }

        public void addPhone(Entity entity, int type, String phone) {
            RowBuilder builder = typedRowBuilder(entity, Phone.CONTENT_ITEM_TYPE, type);
            ContentValues cv = builder.cv;
            if (cv != null && cvCompareString(cv, Phone.NUMBER, phone)) {
                return;
            }
            builder.withValue(Phone.TYPE, type);
            builder.withValue(Phone.NUMBER, phone);
            add(builder.build());
        }

        public void addWebpage(Entity entity, String url) {
            RowBuilder builder = untypedRowBuilder(entity, Website.CONTENT_ITEM_TYPE);
            ContentValues cv = builder.cv;
            if (cv != null && cvCompareString(cv, Website.URL, url)) {
                return;
            }
            builder.withValue(Website.TYPE, Website.TYPE_WORK);
            builder.withValue(Website.URL, url);
            add(builder.build());
        }

        public void addRelation(Entity entity, int type, String value) {
            RowBuilder builder = typedRowBuilder(entity, Relation.CONTENT_ITEM_TYPE, type);
            ContentValues cv = builder.cv;
            if (cv != null && cvCompareString(cv, Relation.DATA, value)) {
                return;
            }
            builder.withValue(Relation.TYPE, type);
            builder.withValue(Relation.DATA, value);
            add(builder.build());
        }

        public void addNickname(Entity entity, String name) {
            RowBuilder builder =
                typedRowBuilder(entity, Nickname.CONTENT_ITEM_TYPE, Nickname.TYPE_DEFAULT);
            ContentValues cv = builder.cv;
            if (cv != null && cvCompareString(cv, Nickname.NAME, name)) {
                return;
            }
            builder.withValue(Nickname.TYPE, Nickname.TYPE_DEFAULT);
            builder.withValue(Nickname.NAME, name);
            add(builder.build());
        }

        public void addPostal(Entity entity, int type, String street, String city, String state,
                String country, String code) {
            RowBuilder builder = typedRowBuilder(entity, StructuredPostal.CONTENT_ITEM_TYPE,
                    type);
            ContentValues cv = builder.cv;
            if (cv != null && cvCompareString(cv, StructuredPostal.CITY, city) &&
                    cvCompareString(cv, StructuredPostal.STREET, street) &&
                    cvCompareString(cv, StructuredPostal.COUNTRY, country) &&
                    cvCompareString(cv, StructuredPostal.POSTCODE, code) &&
                    cvCompareString(cv, StructuredPostal.REGION, state)) {
                return;
            }
            builder.withValue(StructuredPostal.TYPE, type);
            builder.withValue(StructuredPostal.CITY, city);
            builder.withValue(StructuredPostal.STREET, street);
            builder.withValue(StructuredPostal.COUNTRY, country);
            builder.withValue(StructuredPostal.POSTCODE, code);
            builder.withValue(StructuredPostal.REGION, state);
            add(builder.build());
        }

       /**
         * We now are dealing with up to maxRows typeless rows of mimeType data.  We need to try to
         * match them with existing rows; if there's a match, everything's great.  Otherwise, we
         * either need to add a new row for the data, or we have to replace an existing one
         * that no longer matches.  This is similar to the way Emails are handled.
         */
        public void addUntyped(Entity entity, ArrayList<UntypedRow> rows, String mimeType,
                int type, int maxRows) {
            // Make a list of all same type rows in the existing entity
            ArrayList<NamedContentValues> oldValues = EMPTY_ARRAY_NAMEDCONTENTVALUES;
            ArrayList<NamedContentValues> entityValues = EMPTY_ARRAY_NAMEDCONTENTVALUES;
            if (entity != null) {
                oldValues = findUntypedData(entityValues, type, mimeType);
                entityValues = entity.getSubValues();
            }

            // These will be rows needing replacement with new values
            ArrayList<UntypedRow> rowsToReplace = new ArrayList<UntypedRow>();

            // The count of existing rows
            int numRows = oldValues.size();
            for (UntypedRow row: rows) {
                boolean found = false;
                // If we already have this row, mark it
                for (NamedContentValues ncv: oldValues) {
                    ContentValues cv = ncv.values;
                    String data = cv.getAsString(COMMON_DATA_ROW);
                    int rowType = -1;
                    if (cv.containsKey(COMMON_TYPE_ROW)) {
                        rowType = cv.getAsInteger(COMMON_TYPE_ROW);
                    }
                    if (row.isSameAs(rowType, data)) {
                        cv.put(FOUND_DATA_ROW, true);
                        // Remove this to indicate it's still being used
                        entityValues.remove(ncv);
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    // If we don't, there are two possibilities
                    if (numRows < maxRows) {
                        // If there are available rows, add a new one
                        RowBuilder builder = newRowBuilder(entity, mimeType);
                        row.addValues(builder);
                        add(builder.build());
                        numRows++;
                    } else {
                        // Otherwise, say we need to replace a row with this
                        rowsToReplace.add(row);
                    }
                }
            }

            // Go through rows needing replacement
            for (UntypedRow row: rowsToReplace) {
                for (NamedContentValues ncv: oldValues) {
                    ContentValues cv = ncv.values;
                    // Find a row that hasn't been used (i.e. doesn't match current rows)
                    if (!cv.containsKey(FOUND_DATA_ROW)) {
                        // And update it
                        RowBuilder builder = new RowBuilder(
                                ContentProviderOperation
                                    .newUpdate(addCallerIsSyncAdapterParameter(
                                        dataUriFromNamedContentValues(ncv))),
                                ncv);
                        row.addValues(builder);
                        add(builder.build());
                    }
                }
            }
        }

        public void addOrganization(Entity entity, int type, String company, String title,
                String department, String yomiCompanyName, String officeLocation) {
            RowBuilder builder = typedRowBuilder(entity, Organization.CONTENT_ITEM_TYPE, type);
            ContentValues cv = builder.cv;
            if (cv != null && cvCompareString(cv, Organization.COMPANY, company) &&
                    cvCompareString(cv, Organization.PHONETIC_NAME, yomiCompanyName) &&
                    cvCompareString(cv, Organization.DEPARTMENT, department) &&
                    cvCompareString(cv, Organization.TITLE, title) &&
                    cvCompareString(cv, Organization.OFFICE_LOCATION, officeLocation)) {
                return;
            }
            builder.withValue(Organization.TYPE, type);
            builder.withValue(Organization.COMPANY, company);
            builder.withValue(Organization.TITLE, title);
            builder.withValue(Organization.DEPARTMENT, department);
            builder.withValue(Organization.PHONETIC_NAME, yomiCompanyName);
            builder.withValue(Organization.OFFICE_LOCATION, officeLocation);
            add(builder.build());
        }

        public void addNote(Entity entity, String note) {
            RowBuilder builder = typedRowBuilder(entity, Note.CONTENT_ITEM_TYPE, -1);
            ContentValues cv = builder.cv;
            if (note == null) return;
            note = note.replaceAll("\r\n", "\n");
            if (cv != null && cvCompareString(cv, Note.NOTE, note)) {
                return;
            }

            // Reject notes with nothing in them.  Often, we get something from Outlook when
            // nothing was ever entered.  Sigh.
            int len = note.length();
            int i = 0;
            for (; i < len; i++) {
                char c = note.charAt(i);
                if (!Character.isWhitespace(c)) {
                    break;
                }
            }
            if (i == len) return;

            builder.withValue(Note.NOTE, note);
            add(builder.build());
        }
    }

    @Override
    protected void wipe() {
        LogUtils.w(TAG, "Wiping contacts for account %d", mAccount.mId);
        EasSyncContacts.wipeAccountFromContentProvider(mContext,
                mAccount.mEmailAddress);
    }
}
