/*
 * 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.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Directory;
import android.util.Log;

import com.android.contacts.common.util.StopWatch;

import com.google.common.base.Preconditions;

import java.util.Comparator;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Cache object used to cache Smart Dial contacts that handles various states of the cache at the
 * point in time when getContacts() is called
 * 1) Cache is currently empty and there is no caching thread running - getContacts() starts a
 * caching thread and returns the cache when completed
 * 2) The cache is currently empty, but a caching thread has been started - getContacts() waits
 * till the existing caching thread is completed before immediately returning the cache
 * 3) The cache has already been populated, and there is no caching thread running - getContacts()
 * returns the existing cache immediately
 * 4) The cache has already been populated, but there is another caching thread running (due to
 * a forced cache refresh due to content updates - getContacts() returns the existing cache
 * immediately
 */
public class SmartDialCache {

    public static class ContactNumber {
        public final String displayName;
        public final String lookupKey;
        public final long id;
        public final int affinity;
        public final String phoneNumber;

        public ContactNumber(long id, String displayName, String phoneNumber, String lookupKey,
                int affinity) {
            this.displayName = displayName;
            this.lookupKey = lookupKey;
            this.id = id;
            this.affinity = affinity;
            this.phoneNumber = phoneNumber;
        }
    }

    public static interface PhoneQuery {

       Uri URI = Phone.CONTENT_URI.buildUpon().
               appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
               String.valueOf(Directory.DEFAULT)).
               appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true").
               build();

       final String[] PROJECTION_PRIMARY = new String[] {
            Phone._ID,                          // 0
            Phone.TYPE,                         // 1
            Phone.LABEL,                        // 2
            Phone.NUMBER,                       // 3
            Phone.CONTACT_ID,                   // 4
            Phone.LOOKUP_KEY,                   // 5
            Phone.DISPLAY_NAME_PRIMARY,         // 6
        };

        final String[] PROJECTION_ALTERNATIVE = new String[] {
            Phone._ID,                          // 0
            Phone.TYPE,                         // 1
            Phone.LABEL,                        // 2
            Phone.NUMBER,                       // 3
            Phone.CONTACT_ID,                   // 4
            Phone.LOOKUP_KEY,                   // 5
            Phone.DISPLAY_NAME_ALTERNATIVE,     // 6
        };

        public static final int PHONE_ID           = 0;
        public static final int PHONE_TYPE         = 1;
        public static final int PHONE_LABEL        = 2;
        public static final int PHONE_NUMBER       = 3;
        public static final int PHONE_CONTACT_ID   = 4;
        public static final int PHONE_LOOKUP_KEY   = 5;
        public static final int PHONE_DISPLAY_NAME = 6;

        // Current contacts - those contacted within the last 3 days (in milliseconds)
        final static long LAST_TIME_USED_CURRENT_MS = 3 * 24 * 60 * 60 * 1000;

        // Recent contacts - those contacted within the last 30 days (in milliseconds)
        final static long LAST_TIME_USED_RECENT_MS = 30 * 24 * 60 * 60 * 1000;

        final static String TIME_SINCE_LAST_USED_MS =
                "(? - " + Data.LAST_TIME_USED + ")";

        final static String SORT_BY_DATA_USAGE =
                "(CASE WHEN " + TIME_SINCE_LAST_USED_MS + " < " + LAST_TIME_USED_CURRENT_MS +
                " THEN 0 " +
                " WHEN " + TIME_SINCE_LAST_USED_MS + " < " + LAST_TIME_USED_RECENT_MS +
                " THEN 1 " +
                " ELSE 2 END), " +
                Data.TIMES_USED + " DESC";

        // This sort order is similar to that used by the ContactsProvider when returning a list
        // of frequently called contacts.
        public static final String SORT_ORDER =
                Contacts.STARRED + " DESC, "
                + Data.IS_SUPER_PRIMARY + " DESC, "
                + SORT_BY_DATA_USAGE + ", "
                + Contacts.IN_VISIBLE_GROUP + " DESC, "
                + Contacts.DISPLAY_NAME + ", "
                + Data.CONTACT_ID + ", "
                + Data.IS_PRIMARY + " DESC";
    }

    private SmartDialTrie mContactsCache;
    private static AtomicInteger mCacheStatus;
    private final int mNameDisplayOrder;
    private final Context mContext;
    private final static Object mLock = new Object();

    public static final int CACHE_NEEDS_RECACHE = 1;
    public static final int CACHE_IN_PROGRESS = 2;
    public static final int CACHE_COMPLETED = 3;

    private static final boolean DEBUG = false;

    private SmartDialCache(Context context, int nameDisplayOrder) {
        mNameDisplayOrder = nameDisplayOrder;
        Preconditions.checkNotNull(context, "Context must not be null");
        mContext = context.getApplicationContext();
        mCacheStatus = new AtomicInteger(CACHE_NEEDS_RECACHE);
    }

    private static SmartDialCache instance;

    /**
     * Returns an instance of SmartDialCache.
     *
     * @param context A context that provides a valid ContentResolver.
     * @param nameDisplayOrder One of the two name display order integer constants (1 or 2) as saved
     *        in settings under the key
     *        {@link android.provider.ContactsContract.Preferences#DISPLAY_ORDER}.
     * @return An instance of SmartDialCache
     */
    public static synchronized SmartDialCache getInstance(Context context, int nameDisplayOrder) {
        if (instance == null) {
            instance = new SmartDialCache(context, nameDisplayOrder);
        }
        return instance;
    }

    /**
     * Performs a database query, iterates through the returned cursor and saves the retrieved
     * contacts to a local cache.
     */
    private void cacheContacts(Context context) {
        mCacheStatus.set(CACHE_IN_PROGRESS);
        synchronized(mLock) {
            if (DEBUG) {
                Log.d(LOG_TAG, "Starting caching thread");
            }
            final StopWatch stopWatch = DEBUG ? StopWatch.start("SmartDial Cache") : null;
            final String millis = String.valueOf(System.currentTimeMillis());
            final Cursor c = context.getContentResolver().query(PhoneQuery.URI,
                    (mNameDisplayOrder == ContactsContract.Preferences.DISPLAY_ORDER_PRIMARY)
                        ? PhoneQuery.PROJECTION_PRIMARY : PhoneQuery.PROJECTION_ALTERNATIVE,
                    null, new String[] {millis, millis},
                    PhoneQuery.SORT_ORDER);
            if (DEBUG) {
                stopWatch.lap("SmartDial query complete");
            }
            if (c == null) {
                Log.w(LOG_TAG, "SmartDial query received null for cursor");
                if (DEBUG) {
                    stopWatch.stopAndLog("SmartDial query received null for cursor", 0);
                }
                mCacheStatus.getAndSet(CACHE_NEEDS_RECACHE);
                return;
            }
            final SmartDialTrie cache = new SmartDialTrie(
                    SmartDialNameMatcher.LATIN_LETTERS_TO_DIGITS);
            try {
                c.moveToPosition(-1);
                int affinityCount = 0;
                while (c.moveToNext()) {
                    final String displayName = c.getString(PhoneQuery.PHONE_DISPLAY_NAME);
                    final String phoneNumber = c.getString(PhoneQuery.PHONE_NUMBER);
                    final long id = c.getLong(PhoneQuery.PHONE_CONTACT_ID);
                    final String lookupKey = c.getString(PhoneQuery.PHONE_LOOKUP_KEY);
                    cache.put(new ContactNumber(id, displayName, phoneNumber, lookupKey,
                            affinityCount));
                    affinityCount++;
                }
            } finally {
                c.close();
                mContactsCache = cache;
                if (DEBUG) {
                    stopWatch.stopAndLog("SmartDial caching completed", 0);
                }
            }
        }
        if (DEBUG) {
            Log.d(LOG_TAG, "Caching thread completed");
        }
        mCacheStatus.getAndSet(CACHE_COMPLETED);
    }

    /**
     * Returns the list of cached contacts. This is blocking so it should not be called from the UI
     * thread. There are 4 possible scenarios:
     *
     * 1) Cache is currently empty and there is no caching thread running - getContacts() starts a
     * caching thread and returns the cache when completed
     * 2) The cache is currently empty, but a caching thread has been started - getContacts() waits
     * till the existing caching thread is completed before immediately returning the cache
     * 3) The cache has already been populated, and there is no caching thread running -
     * getContacts() returns the existing cache immediately
     * 4) The cache has already been populated, but there is another caching thread running (due to
     * a forced cache refresh due to content updates - getContacts() returns the existing cache
     * immediately
     *
     * @return List of already cached contacts, or an empty list if the caching failed for any
     * reason.
     */
    public SmartDialTrie getContacts() {
        // Either scenario 3 or 4 - This means just go ahead and return the existing cache
        // immediately even if there is a caching thread currently running. We are guaranteed to
        // have the newest value of mContactsCache at this point because it is volatile.
        if (mContactsCache != null) {
            return mContactsCache;
        }
        // At this point we are forced to wait for cacheContacts to complete in another thread(if
        // one currently exists) because of mLock.
        synchronized(mLock) {
            // If mContactsCache is still null at this point, either there was never any caching
            // process running, or it failed (Scenario 1). If so, just go ahead and try to cache
            // the contacts again.
            if (mContactsCache == null) {
                cacheContacts(mContext);
                return (mContactsCache == null) ? new SmartDialTrie(
                        SmartDialNameMatcher.LATIN_LETTERS_TO_DIGITS) : mContactsCache;
            } else {
                // After waiting for the lock on mLock to be released, mContactsCache is now
                // non-null due to the completion of the caching thread (Scenario 2). Go ahead
                // and return the existing cache.
                return mContactsCache;
            }
        }
    }

    /**
     * Cache contacts only if there is a need to (forced cache refresh or no attempt to cache yet).
     * This method is called in 2 places: whenever the DialpadFragment comes into view, and in
     * onResume.
     *
     * @param forceRecache If true, force a cache refresh.
     */

    public void cacheIfNeeded(boolean forceRecache) {
        if (DEBUG) {
            Log.d("SmartDial", "cacheIfNeeded called with " + String.valueOf(forceRecache));
        }
        if (mCacheStatus.get() == CACHE_IN_PROGRESS) {
            return;
        }
        if (forceRecache || mCacheStatus.get() == CACHE_NEEDS_RECACHE) {
            // Because this method can be possibly be called multiple times in rapid succession,
            // set the cache status even before starting a caching thread to avoid unnecessarily
            // spawning extra threads.
            mCacheStatus.set(CACHE_IN_PROGRESS);
            startCachingThread();
        }
    }

    private void startCachingThread() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                cacheContacts(mContext);
            }
        }).start();
    }

    public static class ContactAffinityComparator implements Comparator<ContactNumber> {
        @Override
        public int compare(ContactNumber lhs, ContactNumber rhs) {
            // Smaller affinity is better because they are numbered in ascending order in
            // the order the contacts were returned from the ContactsProvider (sorted by
            // frequency of use and time last used
            return Integer.compare(lhs.affinity, rhs.affinity);
        }

    }
}
