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

    /**
     * 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) {
        }
    };

    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().restartLoader(LOADER_PROFILE, null, mProfileLoaderListener);
    }

    @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));
        }

        // Remove the default account and custom view settings there aren't any writable accounts
        final AccountTypeManager accountTypeManager = AccountTypeManager.getInstance(getContext());
        final List<AccountWithDataSet> accounts = accountTypeManager.getAccounts(
                /* contactWritableOnly */ true);
        if (accounts.isEmpty()) {
            getPreferenceScreen().removePreference(findPreference(KEY_DEFAULT_ACCOUNT));
            getPreferenceScreen().removePreference(findPreference(KEY_CUSTOM_CONTACTS_FILTER));
        }

        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));
        }
    }

    @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();
            }
        }
    }
}

