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

import android.app.Activity;
import android.app.LoaderManager;
import android.content.BroadcastReceiver;
import android.content.ContentUris;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.Loader;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.provider.BlockedNumberContract;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Profile;
import android.support.design.widget.Snackbar;
import android.support.v4.content.LocalBroadcastManager;
import android.telecom.TelecomManager;
import android.telephony.TelephonyManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import com.android.contacts.ContactsUtils;
import com.android.contacts.R;
import com.android.contacts.SimImportService;
import com.android.contacts.compat.TelecomManagerUtil;
import com.android.contacts.compat.TelephonyManagerCompat;
import com.android.contacts.interactions.ExportDialogFragment;
import com.android.contacts.interactions.ImportDialogFragment;
import com.android.contacts.list.ContactListFilter;
import com.android.contacts.list.ContactListFilterController;
import com.android.contacts.logging.ScreenEvent.ScreenType;
import com.android.contacts.model.AccountTypeManager;
import com.android.contacts.model.account.AccountInfo;
import com.android.contacts.model.account.AccountType;
import com.android.contacts.model.account.AccountWithDataSet;
import com.android.contacts.model.account.AccountsLoader;
import com.android.contacts.util.AccountFilterUtil;
import com.android.contacts.util.ImplicitIntentsUtil;
import com.android.contactsbind.HelpUtils;

import java.util.List;

/**
 * This fragment shows the preferences for "display options"
 */
public class DisplayOptionsPreferenceFragment extends PreferenceFragment
        implements Preference.OnPreferenceClickListener {

    private static final int REQUEST_CODE_CUSTOM_CONTACTS_FILTER = 0;

    private static final String ARG_CONTACTS_AVAILABLE = "are_contacts_available";
    private static final String ARG_NEW_LOCAL_PROFILE = "new_local_profile";

    private static final String KEY_ABOUT = "about";
    private static final String KEY_ACCOUNTS = "accounts";
    private static final String KEY_DEFAULT_ACCOUNT = "defaultAccount";
    private static final String KEY_BLOCKED_NUMBERS = "blockedNumbers";
    private static final String KEY_DISPLAY_ORDER = "displayOrder";
    private static final String KEY_CUSTOM_CONTACTS_FILTER = "customContactsFilter";
    private static final String KEY_IMPORT = "import";
    private static final String KEY_EXPORT = "export";
    private static final String KEY_MY_INFO = "myInfo";
    private static final String KEY_SORT_ORDER = "sortOrder";

    private static final int LOADER_PROFILE = 0;
    private static final int LOADER_ACCOUNTS = 1;

    /**
     * Callbacks for hosts of the {@link DisplayOptionsPreferenceFragment}.
     */
    public interface ProfileListener  {
        /**
         * Invoked after profile has been loaded.
         */
        void onProfileLoaded(Cursor data);
    }

    /**
     * The projections that are used to obtain user profile
     */
    public static class ProfileQuery {
        /**
         * Not instantiable.
         */
        private ProfileQuery() {}

        private static final String[] PROFILE_PROJECTION_PRIMARY = new String[] {
                Contacts._ID,                           // 0
                Contacts.DISPLAY_NAME_PRIMARY,          // 1
                Contacts.IS_USER_PROFILE,               // 2
        };

        private static final String[] PROFILE_PROJECTION_ALTERNATIVE = new String[] {
                Contacts._ID,                           // 0
                Contacts.DISPLAY_NAME_ALTERNATIVE,      // 1
                Contacts.IS_USER_PROFILE,               // 2
        };

        public static final int CONTACT_ID               = 0;
        public static final int CONTACT_DISPLAY_NAME     = 1;
        public static final int CONTACT_IS_USER_PROFILE  = 2;
    }

    private String mNewLocalProfileExtra;
    private boolean mAreContactsAvailable;

    private boolean mHasProfile;
    private long mProfileContactId;

    private Preference mMyInfoPreference;

    private ProfileListener mListener;

    private ViewGroup mRootView;
    private SaveServiceResultListener mSaveServiceListener;

    private final LoaderManager.LoaderCallbacks<Cursor> mProfileLoaderListener =
            new LoaderManager.LoaderCallbacks<Cursor>() {

        @Override
        public CursorLoader onCreateLoader(int id, Bundle args) {
            final CursorLoader loader = createCursorLoader(getContext());
            loader.setUri(Profile.CONTENT_URI);
            loader.setProjection(getProjection(getContext()));
            return loader;
        }

        @Override
        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
            if (mListener != null) {
                mListener.onProfileLoaded(data);
            }
        }

        public void onLoaderReset(Loader<Cursor> loader) {
        }
    };

    private final LoaderManager.LoaderCallbacks<List<AccountInfo>> mAccountsLoaderListener =
            new LoaderManager.LoaderCallbacks<List<AccountInfo>>() {
                @Override
                public Loader<List<AccountInfo>> onCreateLoader(int id, Bundle args) {
                    return new AccountsLoader(getActivity(), AccountTypeManager.writableFilter());
                }

                @Override
                public void onLoadFinished(
                        Loader<List<AccountInfo>> loader, List<AccountInfo> data) {
                    if (data.isEmpty()) {
                        removeUnsupportedAccountPreferences();
                    }
                }

                @Override
                public void onLoaderReset(Loader<List<AccountInfo>> loader) {
                }
            };

    public static DisplayOptionsPreferenceFragment newInstance(String newLocalProfileExtra,
            boolean areContactsAvailable) {
        final DisplayOptionsPreferenceFragment fragment = new DisplayOptionsPreferenceFragment();
        final Bundle args = new Bundle();
        args.putString(ARG_NEW_LOCAL_PROFILE, newLocalProfileExtra);
        args.putBoolean(ARG_CONTACTS_AVAILABLE, areContactsAvailable);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (ProfileListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement ProfileListener");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Wrap the preference view in a FrameLayout so we can show a snackbar
        mRootView = new FrameLayout(getActivity());
        final View list = super.onCreateView(inflater, mRootView, savedInstanceState);
        mRootView.addView(list);
        return mRootView;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        mSaveServiceListener = new SaveServiceResultListener();
        LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
                mSaveServiceListener,
                new IntentFilter(SimImportService.BROADCAST_SIM_IMPORT_COMPLETE));
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Load the preferences from an XML resource
        addPreferencesFromResource(R.xml.preference_display_options);

        final Bundle args = getArguments();
        mNewLocalProfileExtra = args.getString(ARG_NEW_LOCAL_PROFILE);
        mAreContactsAvailable = args.getBoolean(ARG_CONTACTS_AVAILABLE);

        removeUnsupportedPreferences();

        mMyInfoPreference = findPreference(KEY_MY_INFO);

        final Preference accountsPreference = findPreference(KEY_ACCOUNTS);
        accountsPreference.setOnPreferenceClickListener(this);

        final Preference importPreference = findPreference(KEY_IMPORT);
        importPreference.setOnPreferenceClickListener(this);

        final Preference exportPreference = findPreference(KEY_EXPORT);
        if (exportPreference != null) {
            exportPreference.setOnPreferenceClickListener(this);
        }

        final Preference blockedNumbersPreference = findPreference(KEY_BLOCKED_NUMBERS);
        if (blockedNumbersPreference != null) {
            blockedNumbersPreference.setOnPreferenceClickListener(this);
        }

        final Preference aboutPreference = findPreference(KEY_ABOUT);
        if (aboutPreference != null) {
            aboutPreference.setOnPreferenceClickListener(this);
        }

        final Preference customFilterPreference = findPreference(KEY_CUSTOM_CONTACTS_FILTER);
        if (customFilterPreference != null) {
            customFilterPreference.setOnPreferenceClickListener(this);
            setCustomContactsFilterSummary();
        }
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        getLoaderManager().initLoader(LOADER_PROFILE, null, mProfileLoaderListener);
        getLoaderManager().initLoader(LOADER_ACCOUNTS, null, mAccountsLoaderListener);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(mSaveServiceListener);
        mRootView = null;
    }

    public void updateMyInfoPreference(boolean hasProfile, String displayName, long contactId) {
        final CharSequence summary = hasProfile ? displayName : getString(R.string.set_up_profile);
        mMyInfoPreference.setSummary(summary);
        mHasProfile = hasProfile;
        mProfileContactId = contactId;
        mMyInfoPreference.setOnPreferenceClickListener(this);
    }

    private void removeUnsupportedPreferences() {
        // Disable sort order for CJK locales where it is not supported
        final Resources resources = getResources();
        if (!resources.getBoolean(R.bool.config_sort_order_user_changeable)) {
            getPreferenceScreen().removePreference(findPreference(KEY_SORT_ORDER));
        }

        if (HelpUtils.isHelpAndFeedbackAvailable()) {
            getPreferenceScreen().removePreference(findPreference(KEY_ABOUT));
        }

        // Disable display order for CJK locales as well
        if (!resources.getBoolean(R.bool.config_display_order_user_changeable)) {
            getPreferenceScreen().removePreference(findPreference(KEY_DISPLAY_ORDER));
        }

        final boolean isPhone = TelephonyManagerCompat.isVoiceCapable(
                (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE));
        final boolean showBlockedNumbers = isPhone && ContactsUtils.FLAG_N_FEATURE
                && BlockedNumberContract.canCurrentUserBlockNumbers(getContext());
        if (!showBlockedNumbers) {
            getPreferenceScreen().removePreference(findPreference(KEY_BLOCKED_NUMBERS));
        }

        if (!mAreContactsAvailable) {
            getPreferenceScreen().removePreference(findPreference(KEY_EXPORT));
        }
    }

    private void removeUnsupportedAccountPreferences() {
        getPreferenceScreen().removePreference(findPreference(KEY_DEFAULT_ACCOUNT));
        getPreferenceScreen().removePreference(findPreference(KEY_CUSTOM_CONTACTS_FILTER));
    }

    @Override
    public Context getContext() {
        return getActivity();
    }

    private CursorLoader createCursorLoader(Context context) {
        return new CursorLoader(context) {
            @Override
            protected Cursor onLoadInBackground() {
                try {
                    return super.onLoadInBackground();
                } catch (RuntimeException e) {
                    return null;
                }
            }
        };
    }

    private String[] getProjection(Context context) {
        final ContactsPreferences contactsPrefs = new ContactsPreferences(context);
        final int displayOrder = contactsPrefs.getDisplayOrder();
        if (displayOrder == ContactsPreferences.DISPLAY_ORDER_PRIMARY) {
            return ProfileQuery.PROFILE_PROJECTION_PRIMARY;
        }
        return ProfileQuery.PROFILE_PROJECTION_ALTERNATIVE;
    }

    @Override
    public boolean onPreferenceClick(Preference p) {
        final String prefKey = p.getKey();

        if (KEY_ABOUT.equals(prefKey)) {
            ((ContactsPreferenceActivity) getActivity()).showAboutFragment();
            return true;
        } else if (KEY_IMPORT.equals(prefKey)) {
            ImportDialogFragment.show(getFragmentManager());
            return true;
        } else if (KEY_EXPORT.equals(prefKey)) {
            ExportDialogFragment.show(getFragmentManager(), ContactsPreferenceActivity.class,
                    ExportDialogFragment.EXPORT_MODE_ALL_CONTACTS);
            return true;
        } else if (KEY_MY_INFO.equals(prefKey)) {
            if (mHasProfile) {
                final Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, mProfileContactId);
                ImplicitIntentsUtil.startQuickContact(getActivity(), uri, ScreenType.ME_CONTACT);
            } else {
                final Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
                intent.putExtra(mNewLocalProfileExtra, true);
                ImplicitIntentsUtil.startActivityInApp(getActivity(), intent);
            }
            return true;
        } else if (KEY_ACCOUNTS.equals(prefKey)) {
            ImplicitIntentsUtil.startActivityOutsideApp(getContext(),
                    ImplicitIntentsUtil.getIntentForAddingAccount());
            return true;
        } else if (KEY_BLOCKED_NUMBERS.equals(prefKey)) {
            final Intent intent = TelecomManagerUtil.createManageBlockedNumbersIntent(
                    (TelecomManager) getContext().getSystemService(Context.TELECOM_SERVICE));
            startActivity(intent);
            return true;
        } else if (KEY_CUSTOM_CONTACTS_FILTER.equals(prefKey)) {
            final ContactListFilter filter =
                    ContactListFilterController.getInstance(getContext()).getFilter();
            AccountFilterUtil.startAccountFilterActivityForResult(
                    this, REQUEST_CODE_CUSTOM_CONTACTS_FILTER, filter);
        }
        return false;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_CODE_CUSTOM_CONTACTS_FILTER
                && resultCode == Activity.RESULT_OK) {
            AccountFilterUtil.handleAccountFilterResult(
                    ContactListFilterController.getInstance(getContext()), resultCode, data);
            setCustomContactsFilterSummary();
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

    private void setCustomContactsFilterSummary() {
        final Preference customFilterPreference = findPreference(KEY_CUSTOM_CONTACTS_FILTER);
        if (customFilterPreference != null) {
            final ContactListFilter filter =
                    ContactListFilterController.getInstance(getContext()).getPersistedFilter();
            if (filter != null) {
                if (filter.filterType == ContactListFilter.FILTER_TYPE_DEFAULT ||
                        filter.filterType == ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS) {
                    customFilterPreference.setSummary(R.string.list_filter_all_accounts);
                } else if (filter.filterType == ContactListFilter.FILTER_TYPE_CUSTOM) {
                    customFilterPreference.setSummary(R.string.listCustomView);
                } else {
                    customFilterPreference.setSummary(null);
                }
            }
        }
    }

    private class SaveServiceResultListener extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            final long now = System.currentTimeMillis();
            final long opStart = intent.getLongExtra(
                    SimImportService.EXTRA_OPERATION_REQUESTED_AT_TIME, now);

            // If it's been over 30 seconds the user is likely in a different context so suppress
            // the toast message.
            if (now - opStart > 30*1000) return;

            final int code = intent.getIntExtra(SimImportService.EXTRA_RESULT_CODE,
                    SimImportService.RESULT_UNKNOWN);
            final int count = intent.getIntExtra(SimImportService.EXTRA_RESULT_COUNT, -1);
            if (code == SimImportService.RESULT_SUCCESS && count > 0) {
                Snackbar.make(mRootView, getResources().getQuantityString(
                        R.plurals.sim_import_success_toast_fmt, count, count),
                        Snackbar.LENGTH_LONG).show();
            } else if (code == SimImportService.RESULT_FAILURE) {
                Snackbar.make(mRootView, R.string.sim_import_failed_toast,
                        Snackbar.LENGTH_LONG).show();
            }
        }
    }
}

