/*
 * 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.contacts.util;

import android.accounts.Account;
import android.app.Activity;
import android.app.Fragment;
import android.content.ActivityNotFoundException;
import android.content.AsyncTaskLoader;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.drawable.Drawable;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Intents;
import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.android.contacts.R;
import com.android.contacts.activities.ContactEditorActivity;
import com.android.contacts.list.AccountFilterActivity;
import com.android.contacts.list.ContactListFilter;
import com.android.contacts.list.ContactListFilterController;
import com.android.contacts.model.AccountTypeManager;
import com.android.contacts.model.Contact;
import com.android.contacts.model.account.AccountDisplayInfo;
import com.android.contacts.model.account.AccountDisplayInfoFactory;
import com.android.contacts.model.account.AccountType;
import com.android.contacts.model.account.AccountWithDataSet;
import com.android.contacts.preference.ContactsPreferences;
import com.android.contacts.util.concurrent.ContactsExecutors;
import com.android.contacts.util.concurrent.ListenableFutureLoader;
import com.android.contactsbind.ObjectFactory;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;

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

import javax.annotation.Nullable;

/**
 * Utility class for account filter manipulation.
 */
public class AccountFilterUtil {
    private static final String TAG = AccountFilterUtil.class.getSimpleName();

     /**
      * Launches account filter setting Activity using
      * {@link Fragment#startActivityForResult(Intent, int)}.
      *
      * @param requestCode requestCode for {@link Activity#startActivityForResult(Intent, int)}
      * @param currentFilter currently-selected filter, so that it can be displayed as activated.
      */
     public static void startAccountFilterActivityForResult(
             Fragment fragment, int requestCode, ContactListFilter currentFilter) {
         final Activity activity = fragment.getActivity();
         if (activity != null) {
             final Intent intent = new Intent(activity, AccountFilterActivity.class);
             fragment.startActivityForResult(intent, requestCode);
         } else {
             Log.w(TAG, "getActivity() returned null. Ignored");
         }
     }

    /**
     * Useful method to handle onActivityResult() for
     * {@link #startAccountFilterActivityForResult(Fragment, int, ContactListFilter)}.
     *
     * This will update filter via a given ContactListFilterController.
     */
    public static void handleAccountFilterResult(
            ContactListFilterController filterController, int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK) {
            final ContactListFilter filter = (ContactListFilter)
                    data.getParcelableExtra(AccountFilterActivity.EXTRA_CONTACT_LIST_FILTER);
            if (filter == null) {
                return;
            }
            if (filter.filterType == ContactListFilter.FILTER_TYPE_CUSTOM) {
                filterController.selectCustomFilter();
            } else {
                filterController.setContactListFilter(filter, /* persistent */
                        filter.filterType == ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS);
            }
        }
    }

    /**
     * Loads a list of contact list filters
     */
    public static class FilterLoader extends ListenableFutureLoader<List<ContactListFilter>> {
        private AccountTypeManager mAccountTypeManager;
        private DeviceLocalAccountTypeFactory mDeviceLocalFactory;
        private LocalBroadcastManager mLocalBroadcastManager;
        private BroadcastReceiver mReceiver;

        public FilterLoader(Context context) {
            super(context);
            mAccountTypeManager = AccountTypeManager.getInstance(context);
            mDeviceLocalFactory = ObjectFactory.getDeviceLocalAccountTypeFactory(context);
            mLocalBroadcastManager = LocalBroadcastManager.getInstance(context);
        }

        @Override
        protected void onStartLoading() {
            super.onStartLoading();
            if (mReceiver == null) {
                mReceiver = new ForceLoadReceiver();
                mLocalBroadcastManager.registerReceiver(mReceiver,
                        new IntentFilter(AccountTypeManager.BROADCAST_ACCOUNTS_CHANGED));
            }
        }

        @Override
        protected void onReset() {
            super.onReset();
            if (mReceiver != null) {
                mLocalBroadcastManager.unregisterReceiver(mReceiver);
            }
        }

        @Override
        protected ListenableFuture<List<ContactListFilter>> loadData() {
            return Futures.transform(mAccountTypeManager.filterAccountsByTypeAsync(
                    AccountTypeManager.writableFilter()),
                    new Function<List<AccountWithDataSet>, List<ContactListFilter>>() {
                        @Override
                        public List<ContactListFilter> apply(List<AccountWithDataSet> input) {
                            return getFiltersForAccounts(input);
                        }
                    }, ContactsExecutors.getDefaultThreadPoolExecutor());
        }

        private List<ContactListFilter> getFiltersForAccounts(List<AccountWithDataSet> accounts) {
            final ArrayList<ContactListFilter> accountFilters = Lists.newArrayList();
            AccountTypeManager.sortAccounts(getDefaultAccount(getContext()), accounts);

            for (AccountWithDataSet account : accounts) {
                final AccountType accountType =
                        mAccountTypeManager.getAccountType(account.type, account.dataSet);
                if ((accountType.isExtension() ||
                        DeviceLocalAccountTypeFactory.Util.isLocalAccountType(
                                mDeviceLocalFactory, account.type)) &&
                        !account.hasData(getContext())) {
                    // Hide extensions and device accounts with no raw_contacts.
                    continue;
                }
                final Drawable icon = accountType != null ?
                        accountType.getDisplayIcon(getContext()) : null;
                if (DeviceLocalAccountTypeFactory.Util.isLocalAccountType(
                        mDeviceLocalFactory, account.type)) {
                    accountFilters.add(ContactListFilter.createDeviceContactsFilter(icon, account));
                } else {
                    accountFilters.add(ContactListFilter.createAccountFilter(
                            account.type, account.name, account.dataSet, icon));
                }
            }

            final ArrayList<ContactListFilter> result = Lists.newArrayList();
            result.addAll(accountFilters);
            return result;
        }
    }

    private static AccountWithDataSet getDefaultAccount(Context context) {
        return new ContactsPreferences(context).getDefaultAccount();
    }

    /**
     * Returns a {@link ContactListFilter} of type
     * {@link ContactListFilter#FILTER_TYPE_ALL_ACCOUNTS}, or if a custom "Contacts to display"
     * filter has been set, then one of type {@link ContactListFilter#FILTER_TYPE_CUSTOM}.
     */
    public static ContactListFilter createContactsFilter(Context context) {
        final int filterType =
                ContactListFilterController.getInstance(context).isCustomFilterPersisted()
                        ? ContactListFilter.FILTER_TYPE_CUSTOM
                        : ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS;
        return ContactListFilter.createFilterWithType(filterType);
    }

    /**
     * Start editor intent; and if filter is an account filter, we pass account info to editor so
     * as to create a contact in that account.
     */
    public static void startEditorIntent(Context context, Intent src, ContactListFilter filter) {
        final Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
        intent.putExtras(src);

        // If we are in account view, we pass the account explicitly in order to
        // create contact in the account. This will prevent the default account dialog
        // from being displayed.
        if (!isAllContactsFilter(filter) && filter.accountName != null
                && filter.accountType != null) {
            final Account account = new Account(filter.accountName, filter.accountType);
            intent.putExtra(Intents.Insert.EXTRA_ACCOUNT, account);
            intent.putExtra(Intents.Insert.EXTRA_DATA_SET, filter.dataSet);
        } else if (isDeviceContactsFilter(filter)) {
            // It's OK to add this even though it's an implicit intent. If a different app
            // receives the intent it should just ignore the flag.
            intent.putExtra(ContactEditorActivity.EXTRA_SAVE_TO_DEVICE_FLAG, true);
        }

        try {
            ImplicitIntentsUtil.startActivityInApp(context, intent);
        } catch (ActivityNotFoundException ex) {
            Toast.makeText(context, R.string.missing_app, Toast.LENGTH_SHORT).show();
        }
    }

    public static boolean isAllContactsFilter(ContactListFilter filter) {
        return filter != null && filter.isContactsFilterType();
    }

    public static boolean isDeviceContactsFilter(ContactListFilter filter) {
        return filter.filterType == ContactListFilter.FILTER_TYPE_DEVICE_CONTACTS;
    }

    /**
     * Returns action bar title for filter and returns default title "Contacts" if filter is empty.
     */
    public static String getActionBarTitleForFilter(Context context, ContactListFilter filter) {
        if (filter.filterType == ContactListFilter.FILTER_TYPE_DEVICE_CONTACTS) {
            return context.getString(R.string.account_phone);
        } else if (filter.filterType == ContactListFilter.FILTER_TYPE_ACCOUNT &&
                !TextUtils.isEmpty(filter.accountName)) {
            return getActionBarTitleForAccount(context, filter);
        }
        return context.getString(R.string.contactsList);
    }

    private static String getActionBarTitleForAccount(Context context, ContactListFilter filter) {
        final AccountDisplayInfoFactory factory =
                AccountDisplayInfoFactory.forAllAccounts(context);
        final AccountDisplayInfo account = factory.getAccountDisplayInfoFor(filter);
        if (account.hasGoogleAccountType()) {
            return context.getString(R.string.title_from_google);
        }
        return account.withFormattedName(context, R.string.title_from_other_accounts)
                .getNameLabel().toString();
    }
}
