/*
 * Copyright (C) 2016 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.contacts.group;

import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Groups;
import android.text.TextUtils;
import android.widget.ImageView;

import com.android.contacts.GroupListLoader;
import com.android.contacts.activities.GroupMembersActivity;
import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
import com.android.contacts.common.list.ContactsSectionIndexer;
import com.android.contacts.common.model.account.GoogleAccountType;
import com.android.contacts.common.testing.NeededForTesting;
import com.google.common.base.Objects;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Group utility methods.
 */
@NeededForTesting
public final class GroupUtil {

    private static final String LEGACY_CONTACTS_AUTHORITY = "contacts";
    private static final String LEGACY_CONTACTS_URI = "content://contacts/groups";

    // System IDs of FFC groups in Google accounts
    private static final Set<String> FFC_GROUPS =
            new HashSet(Arrays.asList("Friends", "Family", "Coworkers"));

    public static final String EXTRA_GROUP_NAME = "groupName";

    private GroupUtil() {
    }

    /** Returns a {@link GroupListItem} read from the given cursor and position. */
    static GroupListItem getGroupListItem(Cursor cursor, int position) {
        if (cursor == null || cursor.isClosed() || !cursor.moveToPosition(position)) {
            return null;
        }
        String accountName = cursor.getString(GroupListLoader.ACCOUNT_NAME);
        String accountType = cursor.getString(GroupListLoader.ACCOUNT_TYPE);
        String dataSet = cursor.getString(GroupListLoader.DATA_SET);
        long groupId = cursor.getLong(GroupListLoader.GROUP_ID);
        String title = cursor.getString(GroupListLoader.TITLE);
        int memberCount = cursor.getInt(GroupListLoader.MEMBER_COUNT);
        boolean isReadOnly = cursor.getInt(GroupListLoader.IS_READ_ONLY) == 1;
        String systemId = cursor.getString(GroupListLoader.SYSTEM_ID);

        // Figure out if this is the first group for this account name / account type pair by
        // checking the previous entry. This is to determine whether or not we need to display an
        // account header in this item.
        int previousIndex = position - 1;
        boolean isFirstGroupInAccount = true;
        if (previousIndex >= 0 && cursor.moveToPosition(previousIndex)) {
            String previousGroupAccountName = cursor.getString(GroupListLoader.ACCOUNT_NAME);
            String previousGroupAccountType = cursor.getString(GroupListLoader.ACCOUNT_TYPE);
            String previousGroupDataSet = cursor.getString(GroupListLoader.DATA_SET);

            if (accountName.equals(previousGroupAccountName) &&
                    accountType.equals(previousGroupAccountType) &&
                    Objects.equal(dataSet, previousGroupDataSet)) {
                isFirstGroupInAccount = false;
            }
        }

        return new GroupListItem(accountName, accountType, dataSet, groupId, title,
                isFirstGroupInAccount, memberCount, isReadOnly, systemId);
    }

    /**
     * @param identifier the {@link ContactPhotoManager.DefaultImageRequest#identifier}
     *         to use for this the group member.
     */
    public static void bindPhoto(ContactPhotoManager photoManager, ImageView imageView,
            long photoId, Uri photoUri, String displayName, String identifier) {
        if (photoId == 0) {
            final DefaultImageRequest defaultImageRequest = photoUri == null
                    ? new DefaultImageRequest(displayName, identifier,
                            /* circularPhotos */ true)
                    : null;
            photoManager.loadDirectoryPhoto(imageView, photoUri, /* darkTheme */ false,
                        /* isCircular */ true, defaultImageRequest);
        } else {
            photoManager.loadThumbnail(imageView, photoId, /* darkTheme */ false,
                        /* isCircular */ true, /* defaultImageRequest */ null);
        }
    }

    /** Returns an Intent to create a new group. */
    public static Intent createAddGroupIntent(Context context) {
        final Intent intent = new Intent(context, GroupMembersActivity.class);
        intent.setAction(Intent.ACTION_INSERT);
        return intent;
    }

    /** Returns an Intent to view the details of the group identified by the given ID. */
    public static Intent createViewGroupIntent(Context context, long groupId, String title) {
        final Intent intent = new Intent(context, GroupMembersActivity.class);
        intent.setAction(Intent.ACTION_VIEW);
        intent.setData(ContentUris.withAppendedId(Groups.CONTENT_URI, groupId));
        intent.putExtra(EXTRA_GROUP_NAME, title);
        return intent;
    }

    /**
     * Converts the given group Uri to the legacy format if the legacy authority was specified
     * in the given Uri.
     */
    // TODO(wjang):
    public static Uri maybeConvertToLegacyUri(Uri groupUri) {
        final String requestAuthority = groupUri.getAuthority();
        if (!LEGACY_CONTACTS_AUTHORITY.equals(requestAuthority)) {
            return groupUri;
        }
        final long groupId = ContentUris.parseId(groupUri);
        final Uri legacyContentUri = Uri.parse(LEGACY_CONTACTS_URI);
        return ContentUris.withAppendedId(legacyContentUri, groupId);
    }

    /**
     * Returns true if it's an empty and read-only group of a Google account and the system ID of
     * the group is one of "Friends", "Family" and "Coworkers".
     */
    public static boolean isEmptyFFCGroup(GroupListItem groupListItem) {
        return GoogleAccountType.ACCOUNT_TYPE.equals(groupListItem.getAccountType())
                && groupListItem.isReadOnly()
                && isSystemIdFFC(groupListItem.getSystemId())
                && (groupListItem.getMemberCount() <= 0);
    }

    private static boolean isSystemIdFFC(String systemId) {
        return !TextUtils.isEmpty(systemId) && FFC_GROUPS.contains(systemId);
    }

    /**
     * Sort groups alphabetically and in a localized way.
     */
    public static String getGroupsSortOrder() {
        return Groups.TITLE + " COLLATE LOCALIZED ASC";
    }

    /**
     * The sum of the last element in counts[] and the last element in positions[] is the total
     * number of remaining elements in cursor. If count is more than what's in the indexer now,
     * then we don't need to trim.
     */
    @NeededForTesting
    public static boolean needTrimming(int count, int[] counts, int[] positions) {
        // The sum of the last element in counts[] and the last element in positions[] is
        // the total number of remaining elements in cursor. If mCount is more than
        // what's in the indexer now, then we don't need to trim.
        return positions.length > 0 && counts.length > 0
                && count <= (counts[counts.length - 1] + positions[positions.length - 1]);
    }

    /**
     * Update Bundle extras so as to update indexer.
     */
    @NeededForTesting
    public static void updateBundle(Bundle bundle, ContactsSectionIndexer indexer,
            List<Integer> subscripts, String[] sections, int[] counts) {
        for (int i : subscripts) {
            final int filteredContact = indexer.getSectionForPosition(i);
            if (filteredContact < counts.length && filteredContact >= 0) {
                counts[filteredContact]--;
                if (counts[filteredContact] == 0) {
                    sections[filteredContact] = "";
                }
            }
        }
        final String[] newSections = clearEmptyString(sections);
        bundle.putStringArray(Contacts.EXTRA_ADDRESS_BOOK_INDEX_TITLES, newSections);
        final int[] newCounts = clearZeros(counts);
        bundle.putIntArray(Contacts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS, newCounts);
    }

    private static String[] clearEmptyString(String[] strings) {
        final List<String> list = new ArrayList<>();
        for (String s : strings) {
            if (!TextUtils.isEmpty(s)) {
                list.add(s);
            }
        }
        return list.toArray(new String[list.size()]);
    }

    private static int[] clearZeros(int[] numbers) {
        final List<Integer> list = new ArrayList<>();
        for (int n : numbers) {
            if (n > 0) {
                list.add(n);
            }
        }
        final int[] array = new int[list.size()];
        for(int i = 0; i < list.size(); i++) {
            array[i] = list.get(i);
        }
        return array;
    }
}