/*
 * Copyright (C) 2009 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.model;

import com.android.contacts.model.ContactsSource.DataKind;
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
import com.google.android.collect.Sets;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AuthenticatorDescription;
import android.accounts.OnAccountsUpdateListener;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.IContentService;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SyncAdapterType;
import android.content.pm.PackageManager;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.text.TextUtils;
import android.util.Log;

import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

/**
 * Singleton holder for all parsed {@link ContactsSource} available on the
 * system, typically filled through {@link PackageManager} queries.
 */
public class Sources extends BroadcastReceiver implements OnAccountsUpdateListener {
    private static final String TAG = "Sources";

    private Context mApplicationContext;
    private AccountManager mAccountManager;

    private ContactsSource mFallbackSource = null;

    private HashMap<String, ContactsSource> mSources = Maps.newHashMap();
    private HashSet<String> mKnownPackages = Sets.newHashSet();

    private static SoftReference<Sources> sInstance = null;

    /**
     * Requests the singleton instance of {@link Sources} with data bound from
     * the available authenticators. This method blocks until its interaction
     * with {@link AccountManager} is finished, so don't call from a UI thread.
     */
    public static synchronized Sources getInstance(Context context) {
        Sources sources = sInstance == null ? null : sInstance.get();
        if (sources == null) {
            sources = new Sources(context);
            sInstance = new SoftReference<Sources>(sources);
        }
        return sources;
    }

    /**
     * Internal constructor that only performs initial parsing.
     */
    private Sources(Context context) {
        mApplicationContext = context.getApplicationContext();
        mAccountManager = AccountManager.get(mApplicationContext);

        // Create fallback contacts source for on-phone contacts
        mFallbackSource = new FallbackSource();

        queryAccounts();

        // Request updates when packages or accounts change
        final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
        filter.addDataScheme("package");

        mApplicationContext.registerReceiver(this, filter);
        mAccountManager.addOnAccountsUpdatedListener(this, null, false);
    }

    /** @hide exposed for unit tests */
    public Sources(ContactsSource... sources) {
        for (ContactsSource source : sources) {
            addSource(source);
        }
    }

    protected void addSource(ContactsSource source) {
        mSources.put(source.accountType, source);
        mKnownPackages.add(source.resPackageName);
    }

    /** {@inheritDoc} */
    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        final String packageName = intent.getData().getSchemeSpecificPart();

        if (Intent.ACTION_PACKAGE_REMOVED.equals(action)
                || Intent.ACTION_PACKAGE_ADDED.equals(action)
                || Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
            final boolean knownPackage = mKnownPackages.contains(packageName);
            if (knownPackage) {
                // Invalidate cache of existing source
                invalidateCache(packageName);
            } else {
                // Unknown source, so reload from scratch
                queryAccounts();
            }
        }
    }

    protected void invalidateCache(String packageName) {
        for (ContactsSource source : mSources.values()) {
            if (TextUtils.equals(packageName, source.resPackageName)) {
                // Invalidate any cache for the changed package
                source.invalidateCache();
            }
        }
    }

    /** {@inheritDoc} */
    public void onAccountsUpdated(Account[] accounts) {
        // Refresh to catch any changed accounts
        queryAccounts();
    }

    /**
     * Blocking call to load all {@link AuthenticatorDescription} known by the
     * {@link AccountManager} on the system.
     */
    protected synchronized void queryAccounts() {
        mSources.clear();
        mKnownPackages.clear();

        final AccountManager am = mAccountManager;
        final IContentService cs = ContentResolver.getContentService();

        try {
            final SyncAdapterType[] syncs = cs.getSyncAdapterTypes();
            final AuthenticatorDescription[] auths = am.getAuthenticatorTypes();

            for (SyncAdapterType sync : syncs) {
                if (!ContactsContract.AUTHORITY.equals(sync.authority)) {
                    // Skip sync adapters that don't provide contact data.
                    continue;
                }

                // Look for the formatting details provided by each sync
                // adapter, using the authenticator to find general resources.
                final String accountType = sync.accountType;
                final AuthenticatorDescription auth = findAuthenticator(auths, accountType);

                ContactsSource source;
                if (GoogleSource.ACCOUNT_TYPE.equals(accountType)) {
                    source = new GoogleSource(auth.packageName);
                } else if (ExchangeSource.ACCOUNT_TYPE.equals(accountType)) {
                    source = new ExchangeSource(auth.packageName);
                } else {
                    // TODO: use syncadapter package instead, since it provides resources
                    Log.d(TAG, "Creating external source for type=" + accountType
                            + ", packageName=" + auth.packageName);
                    source = new ExternalSource(auth.packageName);
                    source.readOnly = !sync.supportsUploading();
                }

                source.accountType = auth.type;
                source.titleRes = auth.labelId;
                source.iconRes = auth.iconId;

                addSource(source);
            }
        } catch (RemoteException e) {
            Log.w(TAG, "Problem loading accounts: " + e.toString());
        }
    }

    /**
     * Find a specific {@link AuthenticatorDescription} in the provided list
     * that matches the given account type.
     */
    protected static AuthenticatorDescription findAuthenticator(AuthenticatorDescription[] auths,
            String accountType) {
        for (AuthenticatorDescription auth : auths) {
            if (accountType.equals(auth.type)) {
                return auth;
            }
        }
        throw new IllegalStateException("Couldn't find authenticator for specific account type");
    }

    /**
     * Return list of all known, writable {@link ContactsSource}. Sources
     * returned may require inflation before they can be used.
     */
    public ArrayList<Account> getAccounts(boolean writableOnly) {
        final AccountManager am = mAccountManager;
        final Account[] accounts = am.getAccounts();
        final ArrayList<Account> matching = Lists.newArrayList();

        for (Account account : accounts) {
            // Ensure we have details loaded for each account
            final ContactsSource source = getInflatedSource(account.type,
                    ContactsSource.LEVEL_SUMMARY);
            final boolean hasContacts = source != null;
            final boolean matchesWritable = (!writableOnly || (writableOnly && !source.readOnly));
            if (hasContacts && matchesWritable) {
                matching.add(account);
            }
        }
        return matching;
    }

    /**
     * Find the best {@link DataKind} matching the requested
     * {@link ContactsSource#accountType} and {@link DataKind#mimeType}. If no
     * direct match found, we try searching {@link #mFallbackSource}.
     */
    public DataKind getKindOrFallback(String accountType, String mimeType, Context context,
            int inflateLevel) {
        DataKind kind = null;

        // Try finding source and kind matching request
        final ContactsSource source = mSources.get(accountType);
        if (source != null) {
            source.ensureInflated(context, inflateLevel);
            kind = source.getKindForMimetype(mimeType);
        }

        if (kind == null) {
            // Nothing found, so try fallback as last resort
            mFallbackSource.ensureInflated(context, inflateLevel);
            kind = mFallbackSource.getKindForMimetype(mimeType);
        }

        if (kind == null) {
            Log.w(TAG, "Unknown type=" + accountType + ", mime=" + mimeType);
        }

        return kind;
    }

    /**
     * Return {@link ContactsSource} for the given account type.
     */
    public ContactsSource getInflatedSource(String accountType, int inflateLevel) {
        // Try finding specific source, otherwise use fallback
        ContactsSource source = mSources.get(accountType);
        if (source == null) source = mFallbackSource;

        if (source.isInflated(inflateLevel)) {
            // Already inflated, so return directly
            return source;
        } else {
            // Not inflated, but requested that we force-inflate
            source.ensureInflated(mApplicationContext, inflateLevel);
            return source;
        }
    }
}
