/*
 * Copyright (C) 2007 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 android.syncml.pim.vcard;

import android.content.AbstractSyncableContentProvider;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.net.Uri;
import android.provider.Contacts;
import android.provider.Contacts.ContactMethods;
import android.provider.Contacts.Extensions;
import android.provider.Contacts.GroupMembership;
import android.provider.Contacts.Organizations;
import android.provider.Contacts.People;
import android.provider.Contacts.Phones;
import android.provider.Contacts.Photos;
import android.syncml.pim.PropertyNode;
import android.syncml.pim.VNode;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.util.Log;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;

/**
 * The parameter class of VCardComposer.
 * This class standy by the person-contact in
 * Android system, we must use this class instance as parameter to transmit to
 * VCardComposer so that create vCard string.
 */
// TODO: rename the class name, next step
public class ContactStruct {
    private static final String LOG_TAG = "ContactStruct";
    
    // Note: phonetic name probably should be "LAST FIRST MIDDLE" for European languages, and
    //       space should be added between each element while it should not be in Japanese.
    //       But unfortunately, we currently do not have the data and are not sure whether we should
    //       support European version of name ordering.
    //
    // TODO: Implement the logic described above if we really need European version of
    //        phonetic name handling. Also, adding the appropriate test case of vCard would be
    //        highly appreciated.
    public static final int NAME_ORDER_TYPE_ENGLISH = 0;
    public static final int NAME_ORDER_TYPE_JAPANESE = 1;

    /** MUST exist */
    public String name;
    public String phoneticName;
    /** maybe folding */
    public List<String> notes = new ArrayList<String>();
    /** maybe folding */
    public String title;
    /** binary bytes of pic. */
    public byte[] photoBytes;
    /** The type of Photo (e.g. JPEG, BMP, etc.) */
    public String photoType;
    /** Only for GET. Use addPhoneList() to PUT. */
    public List<PhoneData> phoneList;
    /** Only for GET. Use addContactmethodList() to PUT. */
    public List<ContactMethod> contactmethodList;
    /** Only for GET. Use addOrgList() to PUT. */
    public List<OrganizationData> organizationList;
    /** Only for GET. Use addExtension() to PUT */
    public Map<String, List<String>> extensionMap;

    // Use organizationList instead when handling ORG.
    @Deprecated
    public String company;
    
    public static class PhoneData {
        public int type;
        /** maybe folding */
        public String data;
        public String label;
        public boolean isPrimary; 
    }

    public static class ContactMethod {
        // Contacts.KIND_EMAIL, Contacts.KIND_POSTAL
        public int kind;
        // e.g. Contacts.ContactMethods.TYPE_HOME, Contacts.PhoneColumns.TYPE_HOME
        // If type == Contacts.PhoneColumns.TYPE_CUSTOM, label is used.
        public int type;
        public String data;
        // Used only when TYPE is TYPE_CUSTOM.
        public String label;
        public boolean isPrimary;
    }
    
    public static class OrganizationData {
        public int type;
        public String companyName;
        public String positionName;
        public boolean isPrimary;
    }

    /**
     * Add a phone info to phoneList.
     * @param data phone number
     * @param type type col of content://contacts/phones
     * @param label lable col of content://contacts/phones
     */
    public void addPhone(int type, String data, String label, boolean isPrimary){
        if (phoneList == null) {
            phoneList = new ArrayList<PhoneData>();
        }
        PhoneData phoneData = new PhoneData();
        phoneData.type = type;
        
        StringBuilder builder = new StringBuilder();
        String trimed = data.trim();
        int length = trimed.length();
        for (int i = 0; i < length; i++) {
            char ch = trimed.charAt(i);
            if (('0' <= ch && ch <= '9') || (i == 0 && ch == '+')) {
                builder.append(ch);
            }
        }
        phoneData.data = PhoneNumberUtils.formatNumber(builder.toString());
        phoneData.label = label;
        phoneData.isPrimary = isPrimary;
        phoneList.add(phoneData);
    }

    /**
     * Add a contactmethod info to contactmethodList.
     * @param kind integer value defined in Contacts.java
     * (e.g. Contacts.KIND_EMAIL)
     * @param type type col of content://contacts/contact_methods
     * @param data contact data
     * @param label extra string used only when kind is Contacts.KIND_CUSTOM.
     */
    public void addContactmethod(int kind, int type, String data,
            String label, boolean isPrimary){
        if (contactmethodList == null) {
            contactmethodList = new ArrayList<ContactMethod>();
        }
        ContactMethod contactMethod = new ContactMethod();
        contactMethod.kind = kind;
        contactMethod.type = type;
        contactMethod.data = data;
        contactMethod.label = label;
        contactMethod.isPrimary = isPrimary;
        contactmethodList.add(contactMethod);
    }
    
    /**
     * Add a Organization info to organizationList.
     */
    public void addOrganization(int type, String companyName, String positionName,
            boolean isPrimary) {
        if (organizationList == null) {
            organizationList = new ArrayList<OrganizationData>();
        }
        OrganizationData organizationData = new OrganizationData();
        organizationData.type = type;
        organizationData.companyName = companyName;
        organizationData.positionName = positionName;
        organizationData.isPrimary = isPrimary;
        organizationList.add(organizationData);
    }

    /**
     * Set "position" value to the appropriate data. If there's more than one
     * OrganizationData objects, the value is set to the last one. If there's no
     * OrganizationData object, a new OrganizationData is created, whose company name is
     * empty.  
     * 
     * TODO: incomplete logic. fix this:
     * 
     * e.g. This assumes ORG comes earlier, but TITLE may come earlier like this, though we do not
     * know how to handle it in general cases...
     * ----
     * TITLE:Software Engineer
     * ORG:Google
     * ----
     */
    public void setPosition(String positionValue) {
        if (organizationList == null) {
            organizationList = new ArrayList<OrganizationData>();
        }
        int size = organizationList.size();
        if (size == 0) {
            addOrganization(Contacts.OrganizationColumns.TYPE_OTHER, "", null, false);
            size = 1;
        }
        OrganizationData lastData = organizationList.get(size - 1);
        lastData.positionName = positionValue;
    }
    
    public void addExtension(PropertyNode propertyNode) {
        if (propertyNode.propValue.length() == 0) {
            return;
        }
        // Now store the string into extensionMap.
        List<String> list;
        String name = propertyNode.propName;
        if (extensionMap == null) {
            extensionMap = new HashMap<String, List<String>>();
        }
        if (!extensionMap.containsKey(name)){
            list = new ArrayList<String>();
            extensionMap.put(name, list);
        } else {
            list = extensionMap.get(name);
        }        
        
        list.add(propertyNode.encode());
    }
    
    private static String getNameFromNProperty(List<String> elems, int nameOrderType) {
        // Family, Given, Middle, Prefix, Suffix. (1 - 5)
        int size = elems.size();
        if (size > 1) {
            StringBuilder builder = new StringBuilder();
            boolean builderIsEmpty = true;
            // Prefix
            if (size > 3 && elems.get(3).length() > 0) {
                builder.append(elems.get(3));
                builderIsEmpty = false;
            }
            String first, second;
            if (nameOrderType == NAME_ORDER_TYPE_JAPANESE) {
                first = elems.get(0);
                second = elems.get(1);
            } else {
                first = elems.get(1);
                second = elems.get(0);
            }
            if (first.length() > 0) {
                if (!builderIsEmpty) {
                    builder.append(' ');
                }
                builder.append(first);
                builderIsEmpty = false;
            }
            // Middle name
            if (size > 2 && elems.get(2).length() > 0) {
                if (!builderIsEmpty) {
                    builder.append(' ');
                }
                builder.append(elems.get(2));
                builderIsEmpty = false;
            }
            if (second.length() > 0) {
                if (!builderIsEmpty) {
                    builder.append(' ');
                }
                builder.append(second);
                builderIsEmpty = false;
            }
            // Suffix
            if (size > 4 && elems.get(4).length() > 0) {
                if (!builderIsEmpty) {
                    builder.append(' ');
                }
                builder.append(elems.get(4));
                builderIsEmpty = false;
            }
            return builder.toString();
        } else if (size == 1) {
            return elems.get(0);
        } else {
            return "";
        }
    }
    
    public static ContactStruct constructContactFromVNode(VNode node,
            int nameOrderType) {
        if (!node.VName.equals("VCARD")) {
            // Impossible in current implementation. Just for safety.
            Log.e(LOG_TAG, "Non VCARD data is inserted.");
            return null;
        }

        // For name, there are three fields in vCard: FN, N, NAME.
        // We prefer FN, which is a required field in vCard 3.0 , but not in vCard 2.1.
        // Next, we prefer NAME, which is defined only in vCard 3.0.
        // Finally, we use N, which is a little difficult to parse.
        String fullName = null;
        String nameFromNProperty = null;

        // Some vCard has "X-PHONETIC-FIRST-NAME", "X-PHONETIC-MIDDLE-NAME", and
        // "X-PHONETIC-LAST-NAME"
        String xPhoneticFirstName = null;
        String xPhoneticMiddleName = null;
        String xPhoneticLastName = null;
        
        ContactStruct contact = new ContactStruct();

        // Each Column of four properties has ISPRIMARY field
        // (See android.provider.Contacts)
        // If false even after the following loop, we choose the first
        // entry as a "primary" entry.
        boolean prefIsSetAddress = false;
        boolean prefIsSetPhone = false;
        boolean prefIsSetEmail = false;
        boolean prefIsSetOrganization = false;
        
        for (PropertyNode propertyNode: node.propList) {
            String name = propertyNode.propName;

            if (TextUtils.isEmpty(propertyNode.propValue)) {
                continue;
            }
            
            if (name.equals("VERSION")) {
                // vCard version. Ignore this.
            } else if (name.equals("FN")) {
                fullName = propertyNode.propValue;
            } else if (name.equals("NAME") && fullName == null) {
                // Only in vCard 3.0. Use this if FN does not exist.
                // Though, note that vCard 3.0 requires FN.
                fullName = propertyNode.propValue;
            } else if (name.equals("N")) {
                nameFromNProperty = getNameFromNProperty(propertyNode.propValue_vector,
                        nameOrderType);
            } else if (name.equals("SORT-STRING")) {
                contact.phoneticName = propertyNode.propValue;
            } else if (name.equals("SOUND")) {
                if (propertyNode.paramMap_TYPE.contains("X-IRMC-N") &&
                        contact.phoneticName == null) {
                    // Some Japanese mobile phones use this field for phonetic name,
                    // since vCard 2.1 does not have "SORT-STRING" type.
                    // Also, in some cases, the field has some ';' in it.
                    // We remove them.
                    StringBuilder builder = new StringBuilder();
                    String value = propertyNode.propValue;
                    int length = value.length();
                    for (int i = 0; i < length; i++) {
                        char ch = value.charAt(i);
                        if (ch != ';') {
                            builder.append(ch);
                        }
                    }
                    contact.phoneticName = builder.toString();
                } else {
                    contact.addExtension(propertyNode);
                }
            } else if (name.equals("ADR")) {
                List<String> values = propertyNode.propValue_vector;
                boolean valuesAreAllEmpty = true;
                for (String value : values) {
                    if (value.length() > 0) {
                        valuesAreAllEmpty = false;
                        break;
                    }
                }
                if (valuesAreAllEmpty) {
                    continue;
                }

                int kind = Contacts.KIND_POSTAL;
                int type = -1;
                String label = "";
                boolean isPrimary = false;
                for (String typeString : propertyNode.paramMap_TYPE) {
                    if (typeString.equals("PREF") && !prefIsSetAddress) {
                        // Only first "PREF" is considered.
                        prefIsSetAddress = true;
                        isPrimary = true;
                    } else if (typeString.equalsIgnoreCase("HOME")) {
                        type = Contacts.ContactMethodsColumns.TYPE_HOME;
                        label = "";
                    } else if (typeString.equalsIgnoreCase("WORK") || 
                            typeString.equalsIgnoreCase("COMPANY")) {
                        // "COMPANY" seems emitted by Windows Mobile, which is not
                        // specifically supported by vCard 2.1. We assume this is same
                        // as "WORK".
                        type = Contacts.ContactMethodsColumns.TYPE_WORK;
                        label = "";
                    } else if (typeString.equalsIgnoreCase("POSTAL")) {
                        kind = Contacts.KIND_POSTAL;
                    } else if (typeString.equalsIgnoreCase("PARCEL") || 
                            typeString.equalsIgnoreCase("DOM") ||
                            typeString.equalsIgnoreCase("INTL")) {
                        // We do not have a kind or type matching these.
                        // TODO: fix this. We may need to split entries into two.
                        // (e.g. entries for KIND_POSTAL and KIND_PERCEL)
                    } else if (typeString.toUpperCase().startsWith("X-") &&
                            type < 0) {
                        type = Contacts.ContactMethodsColumns.TYPE_CUSTOM;
                        label = typeString.substring(2);
                    } else if (type < 0) {
                        // vCard 3.0 allows iana-token. Also some vCard 2.1 exporters
                        // emit non-standard types. We do not handle their values now.
                        type = Contacts.ContactMethodsColumns.TYPE_CUSTOM;
                        label = typeString;
                    }
                }
                // We use "HOME" as default
                if (type < 0) {
                    type = Contacts.ContactMethodsColumns.TYPE_HOME;
                }
                                
                // adr-value    = 0*6(text-value ";") text-value
                //              ; PO Box, Extended Address, Street, Locality, Region, Postal
                //              ; Code, Country Name
                String address;
                List<String> list = propertyNode.propValue_vector;
                int size = list.size();
                if (size > 1) {
                    StringBuilder builder = new StringBuilder();
                    boolean builderIsEmpty = true;
                    if (Locale.getDefault().getCountry().equals(Locale.JAPAN.getCountry())) {
                        // In Japan, the order is reversed.
                        for (int i = size - 1; i >= 0; i--) {
                            String addressPart = list.get(i);
                            if (addressPart.length() > 0) {
                                if (!builderIsEmpty) {
                                    builder.append(' ');
                                }
                                builder.append(addressPart);
                                builderIsEmpty = false;
                            }
                        }
                    } else {
                        for (int i = 0; i < size; i++) {
                            String addressPart = list.get(i);
                            if (addressPart.length() > 0) {
                                if (!builderIsEmpty) {
                                    builder.append(' ');
                                }
                                builder.append(addressPart);
                                builderIsEmpty = false;
                            }
                        }
                    }
                    address = builder.toString().trim();
                } else {
                    address = propertyNode.propValue; 
                }
                contact.addContactmethod(kind, type, address, label, isPrimary);
            } else if (name.equals("ORG")) {
                // vCard specification does not specify other types.
                int type = Contacts.OrganizationColumns.TYPE_WORK;
                boolean isPrimary = false;
                
                for (String typeString : propertyNode.paramMap_TYPE) {
                    if (typeString.equals("PREF") && !prefIsSetOrganization) {
                        // vCard specification officially does not have PREF in ORG.
                        // This is just for safety.
                        prefIsSetOrganization = true;
                        isPrimary = true;
                    }
                    // XXX: Should we cope with X- words?
                }

                List<String> list = propertyNode.propValue_vector; 
                int size = list.size();
                StringBuilder builder = new StringBuilder();
                for (Iterator<String> iter = list.iterator(); iter.hasNext();) {
                    builder.append(iter.next());
                    if (iter.hasNext()) {
                        builder.append(' ');
                    }
                }

                contact.addOrganization(type, builder.toString(), "", isPrimary);
            } else if (name.equals("TITLE")) {
                contact.setPosition(propertyNode.propValue);
            } else if (name.equals("ROLE")) {
                contact.setPosition(propertyNode.propValue);
            } else if (name.equals("PHOTO")) {
                // We prefer PHOTO to LOGO.
                String valueType = propertyNode.paramMap.getAsString("VALUE");
                if (valueType != null && valueType.equals("URL")) {
                    // TODO: do something.
                } else {
                    // Assume PHOTO is stored in BASE64. In that case,
                    // data is already stored in propValue_bytes in binary form.
                    // It should be automatically done by VBuilder (VDataBuilder/VCardDatabuilder) 
                    contact.photoBytes = propertyNode.propValue_bytes;
                    String type = propertyNode.paramMap.getAsString("TYPE");
                    if (type != null) {
                        contact.photoType = type;
                    }
                }
            } else if (name.equals("LOGO")) {
                // When PHOTO is not available this is not URL,
                // we use this instead of PHOTO.
                String valueType = propertyNode.paramMap.getAsString("VALUE");
                if (valueType != null && valueType.equals("URL")) {
                    // TODO: do something.
                } else if (contact.photoBytes == null) {
                    contact.photoBytes = propertyNode.propValue_bytes;
                    String type = propertyNode.paramMap.getAsString("TYPE");
                    if (type != null) {
                        contact.photoType = type;
                    }
                }
            } else if (name.equals("EMAIL")) {
                int type = -1;
                String label = null;
                boolean isPrimary = false;
                for (String typeString : propertyNode.paramMap_TYPE) {
                    if (typeString.equals("PREF") && !prefIsSetEmail) {
                        // Only first "PREF" is considered.
                        prefIsSetEmail = true;
                        isPrimary = true;
                    } else if (typeString.equalsIgnoreCase("HOME")) {
                        type = Contacts.ContactMethodsColumns.TYPE_HOME;
                    } else if (typeString.equalsIgnoreCase("WORK")) {
                        type = Contacts.ContactMethodsColumns.TYPE_WORK;
                    } else if (typeString.equalsIgnoreCase("CELL")) {
                        // We do not have Contacts.ContactMethodsColumns.TYPE_MOBILE yet.
                        type = Contacts.ContactMethodsColumns.TYPE_CUSTOM;
                        label = Contacts.ContactMethodsColumns.MOBILE_EMAIL_TYPE_NAME;
                    } else if (typeString.toUpperCase().startsWith("X-") &&
                            type < 0) {
                        type = Contacts.ContactMethodsColumns.TYPE_CUSTOM;
                        label = typeString.substring(2);
                    } else if (type < 0) {
                        // vCard 3.0 allows iana-token.
                        // We may have INTERNET (specified in vCard spec),
                        // SCHOOL, etc.
                        type = Contacts.ContactMethodsColumns.TYPE_CUSTOM;
                        label = typeString;
                    }
                }
                // We use "OTHER" as default.
                if (type < 0) {
                    type = Contacts.ContactMethodsColumns.TYPE_OTHER;
                }
                contact.addContactmethod(Contacts.KIND_EMAIL,
                        type, propertyNode.propValue,label, isPrimary);
            } else if (name.equals("TEL")) {
                int type = -1;
                String label = null;
                boolean isPrimary = false;
                boolean isFax = false;
                for (String typeString : propertyNode.paramMap_TYPE) {
                    if (typeString.equals("PREF") && !prefIsSetPhone) {
                        // Only first "PREF" is considered.
                        prefIsSetPhone = true;
                        isPrimary = true;
                    } else if (typeString.equalsIgnoreCase("HOME")) {
                        type = Contacts.PhonesColumns.TYPE_HOME;
                    } else if (typeString.equalsIgnoreCase("WORK")) {
                        type = Contacts.PhonesColumns.TYPE_WORK;
                    } else if (typeString.equalsIgnoreCase("CELL")) {
                        type = Contacts.PhonesColumns.TYPE_MOBILE;
                    } else if (typeString.equalsIgnoreCase("PAGER")) {
                        type = Contacts.PhonesColumns.TYPE_PAGER;
                    } else if (typeString.equalsIgnoreCase("FAX")) {
                        isFax = true;
                    } else if (typeString.equalsIgnoreCase("VOICE") ||
                            typeString.equalsIgnoreCase("MSG")) {
                        // Defined in vCard 3.0. Ignore these because they
                        // conflict with "HOME", "WORK", etc.
                        // XXX: do something?
                    } else if (typeString.toUpperCase().startsWith("X-") &&
                            type < 0) {
                        type = Contacts.PhonesColumns.TYPE_CUSTOM;
                        label = typeString.substring(2);
                    } else if (type < 0){
                        // We may have MODEM, CAR, ISDN, etc...
                        type = Contacts.PhonesColumns.TYPE_CUSTOM;
                        label = typeString;
                    }
                }
                // We use "HOME" as default
                if (type < 0) {
                    type = Contacts.PhonesColumns.TYPE_HOME;
                }
                if (isFax) {
                    if (type == Contacts.PhonesColumns.TYPE_HOME) {
                        type = Contacts.PhonesColumns.TYPE_FAX_HOME; 
                    } else if (type == Contacts.PhonesColumns.TYPE_WORK) {
                        type = Contacts.PhonesColumns.TYPE_FAX_WORK; 
                    }
                }

                contact.addPhone(type, propertyNode.propValue, label, isPrimary);
            } else if (name.equals("NOTE")) {
                contact.notes.add(propertyNode.propValue);
            } else if (name.equals("BDAY")) {
                contact.addExtension(propertyNode);
            } else if (name.equals("URL")) {
                contact.addExtension(propertyNode);
            } else if (name.equals("REV")) {                
                // Revision of this VCard entry. I think we can ignore this.
                contact.addExtension(propertyNode);
            } else if (name.equals("UID")) {
                contact.addExtension(propertyNode);
            } else if (name.equals("KEY")) {
                // Type is X509 or PGP? I don't know how to handle this...
                contact.addExtension(propertyNode);
            } else if (name.equals("MAILER")) {
                contact.addExtension(propertyNode);
            } else if (name.equals("TZ")) {
                contact.addExtension(propertyNode);
            } else if (name.equals("GEO")) {
                contact.addExtension(propertyNode);
            } else if (name.equals("NICKNAME")) {
                // vCard 3.0 only.
                contact.addExtension(propertyNode);
            } else if (name.equals("CLASS")) {
                // vCard 3.0 only.
                // e.g. CLASS:CONFIDENTIAL
                contact.addExtension(propertyNode);
            } else if (name.equals("PROFILE")) {
                // VCard 3.0 only. Must be "VCARD". I think we can ignore this.
                contact.addExtension(propertyNode);
            } else if (name.equals("CATEGORIES")) {
                // VCard 3.0 only.
                // e.g. CATEGORIES:INTERNET,IETF,INDUSTRY,INFORMATION TECHNOLOGY
                contact.addExtension(propertyNode);
            } else if (name.equals("SOURCE")) {
                // VCard 3.0 only.
                contact.addExtension(propertyNode);
            } else if (name.equals("PRODID")) {
                // VCard 3.0 only.
                // To specify the identifier for the product that created
                // the vCard object.
                contact.addExtension(propertyNode);
            } else if (name.equals("X-PHONETIC-FIRST-NAME")) {
                xPhoneticFirstName = propertyNode.propValue;
            } else if (name.equals("X-PHONETIC-MIDDLE-NAME")) {
                xPhoneticMiddleName = propertyNode.propValue;
            } else if (name.equals("X-PHONETIC-LAST-NAME")) {
                xPhoneticLastName = propertyNode.propValue;
            } else {
                // Unknown X- words and IANA token.
                contact.addExtension(propertyNode);
            }
        }

        if (fullName != null) {
            contact.name = fullName;
        } else if(nameFromNProperty != null) {
            contact.name = nameFromNProperty;
        } else {
            contact.name = "";
        }

        if (contact.phoneticName == null &&
                (xPhoneticFirstName != null || xPhoneticMiddleName != null ||
                        xPhoneticLastName != null)) {
            // Note: In Europe, this order should be "LAST FIRST MIDDLE". See the comment around
            //       NAME_ORDER_TYPE_* for more detail.
            String first;
            String second;
            if (nameOrderType == NAME_ORDER_TYPE_JAPANESE) {
                first = xPhoneticLastName;
                second = xPhoneticFirstName;
            } else {
                first = xPhoneticFirstName;
                second = xPhoneticLastName;
            }
            StringBuilder builder = new StringBuilder();
            if (first != null) {
                builder.append(first);
            }
            if (xPhoneticMiddleName != null) {
                builder.append(xPhoneticMiddleName);
            }
            if (second != null) {
                builder.append(second);
            }
            contact.phoneticName = builder.toString();
        }
        
        // Remove unnecessary white spaces.
        // It is found that some mobile phone emits  phonetic name with just one white space
        // when a user does not specify one.
        // This logic is effective toward such kind of weird data.
        if (contact.phoneticName != null) {
            contact.phoneticName = contact.phoneticName.trim();
        }

        // If there is no "PREF", we choose the first entries as primary.
        if (!prefIsSetPhone &&
                contact.phoneList != null && 
                contact.phoneList.size() > 0) {
            contact.phoneList.get(0).isPrimary = true;
        }

        if (!prefIsSetAddress && contact.contactmethodList != null) {
            for (ContactMethod contactMethod : contact.contactmethodList) {
                if (contactMethod.kind == Contacts.KIND_POSTAL) {
                    contactMethod.isPrimary = true;
                    break;
                }
            }
        }
        if (!prefIsSetEmail && contact.contactmethodList != null) {
            for (ContactMethod contactMethod : contact.contactmethodList) {
                if (contactMethod.kind == Contacts.KIND_EMAIL) {
                    contactMethod.isPrimary = true;
                    break;
                }
            }
        }
        if (!prefIsSetOrganization &&
                contact.organizationList != null &&
                contact.organizationList.size() > 0) {
            contact.organizationList.get(0).isPrimary = true;
        }
        
        return contact;
    }
    
    public String displayString() {
        if (name.length() > 0) {
            return name;
        }
        if (contactmethodList != null && contactmethodList.size() > 0) {
            for (ContactMethod contactMethod : contactmethodList) {
                if (contactMethod.kind == Contacts.KIND_EMAIL && contactMethod.isPrimary) {
                    return contactMethod.data;
                }
            }
        }
        if (phoneList != null && phoneList.size() > 0) {
            for (PhoneData phoneData : phoneList) {
                if (phoneData.isPrimary) {
                    return phoneData.data;
                }
            }
        }
        return "";
    }
    
    private void pushIntoContentProviderOrResolver(Object contentSomething,
            long myContactsGroupId) {
        ContentResolver resolver = null;
        AbstractSyncableContentProvider provider = null;
        if (contentSomething instanceof ContentResolver) {
            resolver = (ContentResolver)contentSomething;
        } else if (contentSomething instanceof AbstractSyncableContentProvider) {
            provider = (AbstractSyncableContentProvider)contentSomething;
        } else {
            Log.e(LOG_TAG, "Unsupported object came.");
            return;
        }
        
        ContentValues contentValues = new ContentValues();
        contentValues.put(People.NAME, name);
        contentValues.put(People.PHONETIC_NAME, phoneticName);
        
        if (notes.size() > 1) {
            StringBuilder builder = new StringBuilder();
            for (String note : notes) {
                builder.append(note);
                builder.append("\n");
            }
            contentValues.put(People.NOTES, builder.toString());
        } else if (notes.size() == 1){
            contentValues.put(People.NOTES, notes.get(0));
        }
        
        Uri personUri;
        long personId = 0;
        if (resolver != null) {
            personUri = Contacts.People.createPersonInMyContactsGroup(
                    resolver, contentValues);
            if (personUri != null) {
                personId = ContentUris.parseId(personUri);
            }
        } else {
            personUri = provider.insert(People.CONTENT_URI, contentValues);
            if (personUri != null) {
                personId = ContentUris.parseId(personUri);
                ContentValues values = new ContentValues();
                values.put(GroupMembership.PERSON_ID, personId);
                values.put(GroupMembership.GROUP_ID, myContactsGroupId);
                Uri resultUri = provider.insert(GroupMembership.CONTENT_URI, values);
                if (resultUri == null) {
                    Log.e(LOG_TAG, "Faild to insert the person to MyContact.");
                    provider.delete(personUri, null, null);
                    personUri = null;
                }
            }
        }

        if (personUri == null) {
            Log.e(LOG_TAG, "Failed to create the contact.");
            return;
        }
        
        if (photoBytes != null) {
            if (resolver != null) {
                People.setPhotoData(resolver, personUri, photoBytes);
            } else {
                Uri photoUri = Uri.withAppendedPath(personUri, Contacts.Photos.CONTENT_DIRECTORY);
                ContentValues values = new ContentValues();
                values.put(Photos.DATA, photoBytes);
                provider.update(photoUri, values, null, null);
            }
        }
        
        long primaryPhoneId = -1;
        if (phoneList != null && phoneList.size() > 0) {
            for (PhoneData phoneData : phoneList) {
                ContentValues values = new ContentValues();
                values.put(Contacts.PhonesColumns.TYPE, phoneData.type);
                if (phoneData.type == Contacts.PhonesColumns.TYPE_CUSTOM) {
                    values.put(Contacts.PhonesColumns.LABEL, phoneData.label);
                }
                // Already formatted.
                values.put(Contacts.PhonesColumns.NUMBER, phoneData.data);
                
                // Not sure about Contacts.PhonesColumns.NUMBER_KEY ...
                values.put(Contacts.PhonesColumns.ISPRIMARY, 1);
                values.put(Contacts.Phones.PERSON_ID, personId);
                Uri phoneUri;
                if (resolver != null) {
                    phoneUri = resolver.insert(Phones.CONTENT_URI, values);
                } else {
                    phoneUri = provider.insert(Phones.CONTENT_URI, values);
                }
                if (phoneData.isPrimary) {
                    primaryPhoneId = Long.parseLong(phoneUri.getLastPathSegment());
                }
            }
        }
        
        long primaryOrganizationId = -1;
        if (organizationList != null && organizationList.size() > 0) {
            for (OrganizationData organizationData : organizationList) {
                ContentValues values = new ContentValues();
                // Currently, we do not use TYPE_CUSTOM.
                values.put(Contacts.OrganizationColumns.TYPE,
                        organizationData.type);
                values.put(Contacts.OrganizationColumns.COMPANY,
                        organizationData.companyName);
                values.put(Contacts.OrganizationColumns.TITLE,
                        organizationData.positionName);
                values.put(Contacts.OrganizationColumns.ISPRIMARY, 1);
                values.put(Contacts.OrganizationColumns.PERSON_ID, personId);
                
                Uri organizationUri;
                if (resolver != null) {
                    organizationUri = resolver.insert(Organizations.CONTENT_URI, values);
                } else {
                    organizationUri = provider.insert(Organizations.CONTENT_URI, values);
                }
                if (organizationData.isPrimary) {
                    primaryOrganizationId = Long.parseLong(organizationUri.getLastPathSegment());
                }
            }
        }
        
        long primaryEmailId = -1;
        if (contactmethodList != null && contactmethodList.size() > 0) {
            for (ContactMethod contactMethod : contactmethodList) {
                ContentValues values = new ContentValues();
                values.put(Contacts.ContactMethodsColumns.KIND, contactMethod.kind);
                values.put(Contacts.ContactMethodsColumns.TYPE, contactMethod.type);
                if (contactMethod.type == Contacts.ContactMethodsColumns.TYPE_CUSTOM) {
                    values.put(Contacts.ContactMethodsColumns.LABEL, contactMethod.label);
                }
                values.put(Contacts.ContactMethodsColumns.DATA, contactMethod.data);
                values.put(Contacts.ContactMethodsColumns.ISPRIMARY, 1);
                values.put(Contacts.ContactMethods.PERSON_ID, personId);
                
                if (contactMethod.kind == Contacts.KIND_EMAIL) {
                    Uri emailUri;
                    if (resolver != null) {
                        emailUri = resolver.insert(ContactMethods.CONTENT_URI, values);
                    } else {
                        emailUri = provider.insert(ContactMethods.CONTENT_URI, values);
                    }
                    if (contactMethod.isPrimary) {
                        primaryEmailId = Long.parseLong(emailUri.getLastPathSegment());
                    }
                } else {  // probably KIND_POSTAL
                    if (resolver != null) {
                        resolver.insert(ContactMethods.CONTENT_URI, values);
                    } else {
                        provider.insert(ContactMethods.CONTENT_URI, values);
                    }
                }
            }
        }
        
        if (extensionMap != null && extensionMap.size() > 0) {
            ArrayList<ContentValues> contentValuesArray;
            if (resolver != null) {
                contentValuesArray = new ArrayList<ContentValues>();
            } else {
                contentValuesArray = null;
            }
            for (Entry<String, List<String>> entry : extensionMap.entrySet()) {
                String key = entry.getKey();
                List<String> list = entry.getValue();
                for (String value : list) {
                    ContentValues values = new ContentValues();
                    values.put(Extensions.NAME, key);
                    values.put(Extensions.VALUE, value);
                    values.put(Extensions.PERSON_ID, personId);
                    if (resolver != null) {
                        contentValuesArray.add(values);
                    } else {
                        provider.insert(Extensions.CONTENT_URI, values);
                    }
                }
            }
            if (resolver != null) {
                resolver.bulkInsert(Extensions.CONTENT_URI,
                        contentValuesArray.toArray(new ContentValues[0]));
            }
        }
        
        if (primaryPhoneId >= 0 || primaryOrganizationId >= 0 || primaryEmailId >= 0) {
            ContentValues values = new ContentValues();
            if (primaryPhoneId >= 0) {
                values.put(People.PRIMARY_PHONE_ID, primaryPhoneId);
            }
            if (primaryOrganizationId >= 0) {
                values.put(People.PRIMARY_ORGANIZATION_ID, primaryOrganizationId);
            }
            if (primaryEmailId >= 0) {
                values.put(People.PRIMARY_EMAIL_ID, primaryEmailId);
            }
            if (resolver != null) {
                resolver.update(personUri, values, null, null);
            } else {
                provider.update(personUri, values, null, null);
            }
        }
    }

    /**
     * Push this object into database in the resolver.
     */
    public void pushIntoContentResolver(ContentResolver resolver) {
        pushIntoContentProviderOrResolver(resolver, 0);
    }
    
    /**
     * Push this object into AbstractSyncableContentProvider object.
     */
    public void pushIntoAbstractSyncableContentProvider(
            AbstractSyncableContentProvider provider, long myContactsGroupId) {
        boolean successful = false;
        provider.beginBatch();
        try {
            pushIntoContentProviderOrResolver(provider, myContactsGroupId);
            successful = true;
        } finally {
            provider.endBatch(successful);
        }
    }
    
    public boolean isIgnorable() {
        return TextUtils.isEmpty(name) &&
                TextUtils.isEmpty(phoneticName) &&
                (phoneList == null || phoneList.size() == 0) &&
                (contactmethodList == null || contactmethodList.size() == 0);
    }
}
