/*
 * Copyright (C) 2012 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.dialer.dialpad;

import static com.android.dialer.dialpad.SmartDialAdapter.LOG_TAG;

import android.os.AsyncTask;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.telephony.PhoneNumberUtils;
import android.util.Log;

import com.android.contacts.common.preference.ContactsPreferences;
import com.android.contacts.common.util.StopWatch;
import com.android.dialer.dialpad.SmartDialCache.ContactNumber;

import com.google.common.base.Objects;
import com.google.common.collect.Lists;

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

/**
 * This task searches through the provided cache to return the top 3 contacts(ranked by confidence)
 * that match the query, then passes it back to the {@link SmartDialLoaderCallback} through a
 * callback function.
 */
public class SmartDialLoaderTask extends AsyncTask<String, Integer, List<SmartDialEntry>> {

    public interface SmartDialLoaderCallback {
        void setSmartDialAdapterEntries(List<SmartDialEntry> list, String query);
    }

    static private final boolean DEBUG = true; // STOPSHIP change to false.

    private static final int MAX_ENTRIES = 3;

    private final SmartDialCache mContactsCache;

    private final SmartDialLoaderCallback mCallback;

    private final String mQuery;

    /**
     * See {@link ContactsPreferences#getDisplayOrder()}.
     * {@link ContactsContract.Preferences#DISPLAY_ORDER_PRIMARY} (first name first)
     * {@link ContactsContract.Preferences#DISPLAY_ORDER_ALTERNATIVE} (last name first)
     */
    private final SmartDialNameMatcher mNameMatcher;

    public SmartDialLoaderTask(SmartDialLoaderCallback callback, String query,
            SmartDialCache cache) {
        this.mCallback = callback;
        this.mNameMatcher = new SmartDialNameMatcher(PhoneNumberUtils.normalizeNumber(query));
        this.mContactsCache = cache;
        this.mQuery = query;
    }

    @Override
    protected List<SmartDialEntry> doInBackground(String... params) {
        return getContactMatches();
    }

    @Override
    protected void onPostExecute(List<SmartDialEntry> result) {
        if (mCallback != null) {
            mCallback.setSmartDialAdapterEntries(result, mQuery);
        }
    }

    /**
     * Loads all visible contacts with phone numbers and check if their display names match the
     * query.  Return at most {@link #MAX_ENTRIES} {@link SmartDialEntry}'s for the matching
     * contacts.
     */
    private ArrayList<SmartDialEntry> getContactMatches() {

        final SmartDialTrie trie = mContactsCache.getContacts();
        if (DEBUG) {
            Log.d(LOG_TAG, "Size of cache: " + trie.size());
        }

        final StopWatch stopWatch = DEBUG ? StopWatch.start("Start Match") : null;
        final ArrayList<ContactNumber> allMatches = trie.getAllWithPrefix(mNameMatcher.getQuery());
        if (DEBUG) {
            stopWatch.lap("Find matches");
        }
        // Sort matches in order of ascending contact affinity (lower is better)
        Collections.sort(allMatches, new SmartDialCache.ContactAffinityComparator());
        if (DEBUG) {
            stopWatch.lap("Sort");
        }
        final Set<ContactMatch> duplicates = new HashSet<ContactMatch>();
        final ArrayList<SmartDialEntry> candidates = Lists.newArrayList();
        for (ContactNumber contact : allMatches) {
            final ContactMatch contactMatch = new ContactMatch(contact.lookupKey, contact.id);
            // Don't add multiple contact numbers from the same contact into suggestions if
            // there are multiple matches. Instead, just keep the highest priority number
            // instead.
            if (duplicates.contains(contactMatch)) {
                continue;
            }
            duplicates.add(contactMatch);
            final boolean matches = mNameMatcher.matches(contact.displayName);
            candidates.add(new SmartDialEntry(
                    contact.displayName,
                    Contacts.getLookupUri(contact.id, contact.lookupKey),
                    contact.phoneNumber,
                    mNameMatcher.getMatchPositions(),
                    mNameMatcher.matchesNumber(contact.phoneNumber, mNameMatcher.getQuery())
                    ));
            if (candidates.size() >= MAX_ENTRIES) {
                break;
            }
        }
        if (DEBUG) {
            stopWatch.stopAndLog(LOG_TAG + " Match Complete", 0);
        }
        return candidates;
    }

    private class ContactMatch {
        public final String lookupKey;
        public final long id;

        public ContactMatch(String lookupKey, long id) {
            this.lookupKey = lookupKey;
            this.id = id;
        }

        @Override
        public int hashCode() {
            return Objects.hashCode(lookupKey, id);
        }

        @Override
        public boolean equals(Object object) {
            if (this == object) {
                return true;
            }
            if (object instanceof ContactMatch) {
                ContactMatch that = (ContactMatch) object;
                return Objects.equal(this.lookupKey, that.lookupKey)
                        && Objects.equal(this.id, that.id);
            }
            return false;
        }
    }
}
