/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.car.telephony.common;

import android.content.Context;
import android.database.Cursor;
import android.icu.text.Collator;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.ContactsContract;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.ArrayList;
import java.util.List;

/**
 * Encapsulates data about a phone Contact entry. Typically loaded from the local Contact store.
 */
public class Contact implements Parcelable, Comparable<Contact> {
    private static final String TAG = "CD.Contact";

    /**
     * Column name for phonebook label column.
     */
    private static final String PHONEBOOK_LABEL = "phonebook_label";
    /**
     * Column name for alternative phonebook label column.
     */
    private static final String PHONEBOOK_LABEL_ALT = "phonebook_label_alt";

    /**
     * Contact belongs to TYPE_LETTER if its display name starts with a letter
     */
    private static final int TYPE_LETTER = 1;
    /**
     * Contact belongs to TYPE_DIGIT if its display name starts with a digit
     */
    private static final int TYPE_DIGIT = 2;
    /**
     * Contact belongs to TYPE_OTHER if it does not belong to TYPE_LETTER or TYPE_DIGIT Such as
     * empty display name or the display name starts with "_"
     */
    private static final int TYPE_OTHER = 3;

    /**
     * A reference to the {@link ContactsContract.RawContacts#CONTACT_ID}.
     */
    private long mContactId;

    /**
     * A reference to the {@link ContactsContract.Data#RAW_CONTACT_ID}.
     */
    private long mRawContactId;

    /**
     * The name of the account instance to which this row belongs, which identifies a specific
     * account. See {@link ContactsContract.RawContacts#ACCOUNT_NAME}.
     */
    private String mAccountName;

    /**
     * The display name.
     * <p>
     * The standard text shown as the contact's display name, based on the best available
     * information for the contact.
     * </p>
     * <p>
     * See {@link ContactsContract.CommonDataKinds.Phone#DISPLAY_NAME}.
     */
    private String mDisplayName;

    /**
     * The alternative display name.
     * <p>
     * An alternative representation of the display name, such as "family name first" instead of
     * "given name first" for Western names.  If an alternative is not available, the values should
     * be the same as {@link #mDisplayName}.
     * </p>
     * <p>
     * See {@link ContactsContract.CommonDataKinds.Phone#DISPLAY_NAME_ALTERNATIVE}.
     */
    private String mDisplayNameAlt;

    /**
     * The given name for the contact. See
     * {@link ContactsContract.CommonDataKinds.StructuredName#GIVEN_NAME}.
     */
    private String mGivenName;

    /**
     * The family name for the contact. See
     * {@link ContactsContract.CommonDataKinds.StructuredName#FAMILY_NAME}.
     */
    private String mFamilyName;

    /**
     * The initials of the contact's name.
     */
    private String mInitials;

    /**
     * The phonebook label.
     * <p>
     * For {@link #mDisplayName}s starting with letters, label will be the first character of {@link
     * #mDisplayName}. For {@link #mDisplayName}s starting with numbers, the label will be "#". For
     * {@link #mDisplayName}s starting with other characters, the label will be "...".
     * </p>
     */
    private String mPhoneBookLabel;

    /**
     * The alternative phonebook label.
     * <p>
     * It is similar with {@link #mPhoneBookLabel}. But instead of generating from {@link
     * #mDisplayName}, it will use {@link #mDisplayNameAlt}.
     * </p>
     */
    private String mPhoneBookLabelAlt;

    /**
     * Sort key that takes into account locale-based traditions for sorting names in address books.
     * <p>
     * See {@link ContactsContract.CommonDataKinds.Phone#SORT_KEY_PRIMARY}.
     */
    private String mSortKeyPrimary;

    /**
     * Sort key based on the alternative representation of the full name.
     * <p>
     * See {@link ContactsContract.CommonDataKinds.Phone#SORT_KEY_ALTERNATIVE}.
     */
    private String mSortKeyAlt;

    /**
     * An opaque value that contains hints on how to find the contact if its row id changed as a
     * result of a sync or aggregation. If a contact has multiple phone numbers, all phone numbers
     * are recorded in a single entry and they all have the same look up key in a single load. See
     * {@link ContactsContract.Data#LOOKUP_KEY}.
     */
    private String mLookupKey;

    /**
     * A URI that can be used to retrieve a thumbnail of the contact's photo.
     */
    @Nullable
    private Uri mAvatarThumbnailUri;

    /**
     * A URI that can be used to retrieve the contact's full-size photo.
     */
    @Nullable
    private Uri mAvatarUri;

    /**
     * Whether this contact entry is starred by user.
     */
    private boolean mIsStarred;

    /**
     * Contact-specific information about whether or not a contact has been pinned by the user at a
     * particular position within the system contact application's user interface.
     */
    private int mPinnedPosition;

    /**
     * This contact's primary phone number. Its value is null if a primary phone number is not set.
     */
    @Nullable
    private PhoneNumber mPrimaryPhoneNumber;

    /**
     * Whether this contact represents a voice mail.
     */
    private boolean mIsVoiceMail;

    /**
     * All phone numbers of this contact mapping to the unique primary key for the raw data entry.
     */
    private final List<PhoneNumber> mPhoneNumbers = new ArrayList<>();

    /**
     * All postal addresses of this contact mapping to the unique primary key for the raw data
     * entry
     */
    private final List<PostalAddress> mPostalAddresses = new ArrayList<>();

    /**
     * Parses a contact entry for a Cursor loaded from the Contact Database. A new contact will be
     * created and returned.
     */
    public static Contact fromCursor(Context context, Cursor cursor) {
        return fromCursor(context, cursor, null);
    }

    /**
     * Parses a contact entry for a Cursor loaded from the Contact Database.
     *
     * @param contact should have the same {@link #mLookupKey} and {@link #mAccountName} with the
     *                data read from the cursor, so all the data from the cursor can be loaded into
     *                this contact. If either of their {@link #mLookupKey} and {@link #mAccountName}
     *                is not the same or this contact is null, a new contact will be created and
     *                returned.
     */
    public static Contact fromCursor(Context context, Cursor cursor, @Nullable Contact contact) {
        int accountNameColumn = cursor.getColumnIndex(ContactsContract.RawContacts.ACCOUNT_NAME);
        int lookupKeyColumn = cursor.getColumnIndex(ContactsContract.Data.LOOKUP_KEY);
        String accountName = cursor.getString(accountNameColumn);
        String lookupKey = cursor.getString(lookupKeyColumn);

        if (contact == null) {
            Log.d(TAG, "A new contact will be created.");
            contact = new Contact();
            contact.loadBasicInfo(cursor);
        }

        if (!TextUtils.equals(accountName, contact.mAccountName)
                || !TextUtils.equals(lookupKey, contact.mLookupKey)) {
            Log.w(TAG, "A wrong contact is passed in. A new contact will be created.");
            contact = new Contact();
            contact.loadBasicInfo(cursor);
        }

        int mimetypeColumn = cursor.getColumnIndex(ContactsContract.Data.MIMETYPE);
        String mimeType = cursor.getString(mimetypeColumn);

        // More mimeType can be added here if more types of data needs to be loaded.
        switch (mimeType) {
            case ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE:
                contact.loadNameDetails(cursor);
                break;
            case ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE:
                contact.addPhoneNumber(context, cursor);
                break;
            case ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE:
                contact.addPostalAddress(cursor);
                break;
            default:
                Log.d(TAG,
                        String.format("This mimetype %s will not be loaded right now.", mimeType));
        }

        return contact;
    }

    /**
     * The data columns that are the same in every cursor no matter what the mimetype is will be
     * loaded here.
     */
    private void loadBasicInfo(Cursor cursor) {
        int contactIdColumn = cursor.getColumnIndex(ContactsContract.RawContacts.CONTACT_ID);
        int rawContactIdColumn = cursor.getColumnIndex(ContactsContract.Data.RAW_CONTACT_ID);
        int accountNameColumn = cursor.getColumnIndex(ContactsContract.RawContacts.ACCOUNT_NAME);
        int displayNameColumn = cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME);
        int displayNameAltColumn = cursor.getColumnIndex(
                ContactsContract.RawContacts.DISPLAY_NAME_ALTERNATIVE);
        int phoneBookLabelColumn = cursor.getColumnIndex(PHONEBOOK_LABEL);
        int phoneBookLabelAltColumn = cursor.getColumnIndex(PHONEBOOK_LABEL_ALT);
        int sortKeyPrimaryColumn = cursor.getColumnIndex(
                ContactsContract.RawContacts.SORT_KEY_PRIMARY);
        int sortKeyAltColumn = cursor.getColumnIndex(
                ContactsContract.RawContacts.SORT_KEY_ALTERNATIVE);
        int lookupKeyColumn = cursor.getColumnIndex(ContactsContract.Data.LOOKUP_KEY);

        int avatarUriColumn = cursor.getColumnIndex(ContactsContract.Data.PHOTO_URI);
        int avatarThumbnailColumn = cursor.getColumnIndex(
                ContactsContract.Data.PHOTO_THUMBNAIL_URI);
        int starredColumn = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.STARRED);
        int pinnedColumn = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PINNED);

        mContactId = cursor.getLong(contactIdColumn);
        mRawContactId = cursor.getLong(rawContactIdColumn);
        mAccountName = cursor.getString(accountNameColumn);
        mDisplayName = cursor.getString(displayNameColumn);
        mDisplayNameAlt = cursor.getString(displayNameAltColumn);
        mSortKeyPrimary = cursor.getString(sortKeyPrimaryColumn);
        mSortKeyAlt = cursor.getString(sortKeyAltColumn);
        mPhoneBookLabel = cursor.getString(phoneBookLabelColumn);
        mPhoneBookLabelAlt = cursor.getString(phoneBookLabelAltColumn);
        mLookupKey = cursor.getString(lookupKeyColumn);

        String avatarUriStr = cursor.getString(avatarUriColumn);
        mAvatarUri = avatarUriStr == null ? null : Uri.parse(avatarUriStr);
        String avatarThumbnailStringUri = cursor.getString(avatarThumbnailColumn);
        mAvatarThumbnailUri = avatarThumbnailStringUri == null ? null : Uri.parse(
                avatarThumbnailStringUri);

        mIsStarred = cursor.getInt(starredColumn) > 0;
        mPinnedPosition = cursor.getInt(pinnedColumn);
    }

    /**
     * Loads the data whose mimetype is
     * {@link ContactsContract.CommonDataKinds.StructuredName#CONTENT_ITEM_TYPE}.
     */
    private void loadNameDetails(Cursor cursor) {
        int firstNameColumn = cursor.getColumnIndex(
                ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
        int lastNameColumn = cursor.getColumnIndex(
                ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME);

        mGivenName = cursor.getString(firstNameColumn);
        mFamilyName = cursor.getString(lastNameColumn);
    }

    /**
     * Loads the data whose mimetype is
     * {@link ContactsContract.CommonDataKinds.Phone#CONTENT_ITEM_TYPE}.
     */
    private void addPhoneNumber(Context context, Cursor cursor) {
        PhoneNumber newNumber = PhoneNumber.fromCursor(context, cursor);

        boolean hasSameNumber = false;
        for (PhoneNumber number : mPhoneNumbers) {
            if (newNumber.equals(number)) {
                hasSameNumber = true;
                number.merge(newNumber);
            }
        }

        if (!hasSameNumber) {
            mPhoneNumbers.add(newNumber);
        }

        if (newNumber.isPrimary()) {
            mPrimaryPhoneNumber = newNumber.merge(mPrimaryPhoneNumber);
        }

        // TODO: update voice mail number part when start to support voice mail.
        if (TelecomUtils.isVoicemailNumber(context, newNumber.getNumber())) {
            mIsVoiceMail = true;
        }
    }

    /**
     * Loads the data whose mimetype is
     * {@link ContactsContract.CommonDataKinds.StructuredPostal#CONTENT_ITEM_TYPE}.
     */
    private void addPostalAddress(Cursor cursor) {
        PostalAddress newAddress = PostalAddress.fromCursor(cursor);

        if (!mPostalAddresses.contains(newAddress)) {
            mPostalAddresses.add(newAddress);
        }
    }

    @Override
    public boolean equals(Object obj) {
        return obj instanceof Contact && mLookupKey.equals(((Contact) obj).mLookupKey)
                && mAccountName.equals(((Contact) obj).mAccountName);
    }

    @Override
    public int hashCode() {
        return mLookupKey.hashCode();
    }

    @Override
    public String toString() {
        return mDisplayName + mPhoneNumbers;
    }

    /**
     * Returns the aggregated contact id.
     */
    public long getId() {
        return mContactId;
    }

    /**
     * Returns the raw contact id.
     */
    public long getRawContactId() {
        return mRawContactId;
    }

    /**
     * Returns a lookup uri using {@link #mContactId} and {@link #mLookupKey}. Returns null if
     * unable to get a valid lookup URI from the provided parameters. See {@link
     * ContactsContract.Contacts#getLookupUri(long, String)}.
     */
    @Nullable
    public Uri getLookupUri() {
        return ContactsContract.Contacts.getLookupUri(mContactId, mLookupKey);
    }

    /**
     * Returns {@link #mAccountName}.
     */
    public String getAccountName() {
        return mAccountName;
    }

    /**
     * Returns {@link #mDisplayName}.
     */
    public String getDisplayName() {
        return mDisplayName;
    }

    /**
     * Returns {@link #mDisplayNameAlt}.
     */
    public String getDisplayNameAlt() {
        return mDisplayNameAlt;
    }

    /**
     * Returns {@link #mGivenName}.
     */
    public String getGivenName() {
        return mGivenName;
    }

    /**
     * Returns {@link #mFamilyName}.
     */
    public String getFamilyName() {
        return mFamilyName;
    }

    /**
     * Returns the initials of the contact's name.
     */
    //TODO: update how to get initials after refactoring. Could use last name and first name to
    // get initials after refactoring to avoid error for those names with prefix.
    public String getInitials() {
        if (mInitials == null) {
            mInitials = TelecomUtils.getInitials(mDisplayName, mDisplayNameAlt);
        }

        return mInitials;
    }

    /**
     * Returns {@link #mPhoneBookLabel}
     */
    public String getPhonebookLabel() {
        return mPhoneBookLabel;
    }

    /**
     * Returns {@link #mPhoneBookLabelAlt}
     */
    public String getPhonebookLabelAlt() {
        return mPhoneBookLabelAlt;
    }

    /**
     * Returns {@link #mLookupKey}.
     */
    public String getLookupKey() {
        return mLookupKey;
    }

    /**
     * Returns the Uri for avatar.
     */
    @Nullable
    public Uri getAvatarUri() {
        return mAvatarUri != null ? mAvatarUri : mAvatarThumbnailUri;
    }

    /**
     * Return all phone numbers associated with this contact.
     */
    public List<PhoneNumber> getNumbers() {
        return mPhoneNumbers;
    }

    /**
     * Return all postal addresses associated with this contact.
     */
    public List<PostalAddress> getPostalAddresses() {
        return mPostalAddresses;
    }

    /**
     * Returns if this Contact represents a voice mail number.
     */
    public boolean isVoicemail() {
        return mIsVoiceMail;
    }

    /**
     * Returns if this contact has a primary phone number.
     */
    public boolean hasPrimaryPhoneNumber() {
        return mPrimaryPhoneNumber != null;
    }

    /**
     * Returns the primary phone number for this Contact. Returns null if there is not one.
     */
    @Nullable
    public PhoneNumber getPrimaryPhoneNumber() {
        return mPrimaryPhoneNumber;
    }

    /**
     * Returns if this Contact is starred.
     */
    public boolean isStarred() {
        return mIsStarred;
    }

    /**
     * Returns {@link #mPinnedPosition}.
     */
    public int getPinnedPosition() {
        return mPinnedPosition;
    }

    /**
     * Looks up a {@link PhoneNumber} of this contact for the given phone number string. Returns
     * {@code null} if this contact doesn't contain the given phone number.
     */
    @Nullable
    public PhoneNumber getPhoneNumber(Context context, String number) {
        I18nPhoneNumberWrapper i18nPhoneNumber = I18nPhoneNumberWrapper.Factory.INSTANCE.get(
                context, number);
        for (PhoneNumber phoneNumber : mPhoneNumbers) {
            if (phoneNumber.getI18nPhoneNumberWrapper().equals(i18nPhoneNumber)) {
                return phoneNumber;
            }
        }
        return null;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(mContactId);
        dest.writeLong(mRawContactId);
        dest.writeString(mLookupKey);
        dest.writeString(mAccountName);
        dest.writeString(mDisplayName);
        dest.writeString(mDisplayNameAlt);
        dest.writeString(mSortKeyPrimary);
        dest.writeString(mSortKeyAlt);
        dest.writeString(mPhoneBookLabel);
        dest.writeString(mPhoneBookLabelAlt);
        dest.writeParcelable(mAvatarThumbnailUri, 0);
        dest.writeParcelable(mAvatarUri, 0);
        dest.writeBoolean(mIsStarred);
        dest.writeInt(mPinnedPosition);

        dest.writeBoolean(mIsVoiceMail);
        dest.writeParcelable(mPrimaryPhoneNumber, flags);
        dest.writeInt(mPhoneNumbers.size());
        for (PhoneNumber phoneNumber : mPhoneNumbers) {
            dest.writeParcelable(phoneNumber, flags);
        }

        dest.writeInt(mPostalAddresses.size());
        for (PostalAddress postalAddress : mPostalAddresses) {
            dest.writeParcelable(postalAddress, flags);
        }
    }

    public static final Creator<Contact> CREATOR = new Creator<Contact>() {
        @Override
        public Contact createFromParcel(Parcel source) {
            return Contact.fromParcel(source);
        }

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

    /**
     * Create {@link Contact} object from saved parcelable.
     */
    private static Contact fromParcel(Parcel source) {
        Contact contact = new Contact();
        contact.mContactId = source.readLong();
        contact.mRawContactId = source.readLong();
        contact.mLookupKey = source.readString();
        contact.mAccountName = source.readString();
        contact.mDisplayName = source.readString();
        contact.mDisplayNameAlt = source.readString();
        contact.mSortKeyPrimary = source.readString();
        contact.mSortKeyAlt = source.readString();
        contact.mPhoneBookLabel = source.readString();
        contact.mPhoneBookLabelAlt = source.readString();
        contact.mAvatarThumbnailUri = source.readParcelable(Uri.class.getClassLoader());
        contact.mAvatarUri = source.readParcelable(Uri.class.getClassLoader());
        contact.mIsStarred = source.readBoolean();
        contact.mPinnedPosition = source.readInt();

        contact.mIsVoiceMail = source.readBoolean();
        contact.mPrimaryPhoneNumber = source.readParcelable(PhoneNumber.class.getClassLoader());
        int phoneNumberListLength = source.readInt();
        for (int i = 0; i < phoneNumberListLength; i++) {
            PhoneNumber phoneNumber = source.readParcelable(PhoneNumber.class.getClassLoader());
            contact.mPhoneNumbers.add(phoneNumber);
            if (phoneNumber.isPrimary()) {
                contact.mPrimaryPhoneNumber = phoneNumber;
            }
        }

        int postalAddressListLength = source.readInt();
        for (int i = 0; i < postalAddressListLength; i++) {
            PostalAddress address = source.readParcelable(PostalAddress.class.getClassLoader());
            contact.mPostalAddresses.add(address);
        }

        return contact;
    }

    @Override
    public int compareTo(Contact otherContact) {
        // Use a helper function to classify Contacts
        // and by default, it should be compared by first name order.
        return compareBySortKeyPrimary(otherContact);
    }

    /**
     * Compares contacts by their {@link #mSortKeyPrimary} in an order of letters, numbers, then
     * special characters.
     */
    public int compareBySortKeyPrimary(@NonNull Contact otherContact) {
        return compareNames(mSortKeyPrimary, otherContact.mSortKeyPrimary,
                mPhoneBookLabel, otherContact.getPhonebookLabel());
    }

    /**
     * Compares contacts by their {@link #mSortKeyAlt} in an order of letters, numbers, then special
     * characters.
     */
    public int compareBySortKeyAlt(@NonNull Contact otherContact) {
        return compareNames(mSortKeyAlt, otherContact.mSortKeyAlt,
                mPhoneBookLabelAlt, otherContact.getPhonebookLabelAlt());
    }

    /**
     * Compares two strings in an order of letters, numbers, then special characters.
     */
    private int compareNames(String name, String otherName, String label, String otherLabel) {
        int type = getNameType(label);
        int otherType = getNameType(otherLabel);
        if (type != otherType) {
            return Integer.compare(type, otherType);
        }
        Collator collator = Collator.getInstance();
        return collator.compare(name == null ? "" : name, otherName == null ? "" : otherName);
    }

    /**
     * Returns the type of the name string. Types can be {@link #TYPE_LETTER}, {@link #TYPE_DIGIT}
     * and {@link #TYPE_OTHER}.
     */
    private static int getNameType(String label) {
        // A helper function to classify Contacts
        if (!TextUtils.isEmpty(label)) {
            if (Character.isLetter(label.charAt(0))) {
                return TYPE_LETTER;
            }
            if (label.contains("#")) {
                return TYPE_DIGIT;
            }
        }
        return TYPE_OTHER;
    }
}
