/*
 * Copyright (C) 2011 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.settings.bluetooth;

import android.app.AlertDialog;
import android.app.Dialog;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import androidx.annotation.VisibleForTesting;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;

import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settingslib.bluetooth.A2dpProfile;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfile;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.settingslib.bluetooth.MapProfile;
import com.android.settingslib.bluetooth.PanProfile;
import com.android.settingslib.bluetooth.PbapServerProfile;

public final class DeviceProfilesSettings extends InstrumentedDialogFragment implements
        CachedBluetoothDevice.Callback, DialogInterface.OnClickListener, OnClickListener {
    private static final String TAG = "DeviceProfilesSettings";

    public static final String ARG_DEVICE_ADDRESS = "device_address";

    private static final String KEY_PROFILE_CONTAINER = "profile_container";
    private static final String KEY_UNPAIR = "unpair";
    private static final String KEY_PBAP_SERVER = "PBAP Server";
    @VisibleForTesting
    static final String HIGH_QUALITY_AUDIO_PREF_TAG = "A2dpProfileHighQualityAudio";

    private CachedBluetoothDevice mCachedDevice;
    private LocalBluetoothManager mManager;
    private LocalBluetoothProfileManager mProfileManager;

    private ViewGroup mProfileContainer;
    private TextView mProfileLabel;

    private AlertDialog mDisconnectDialog;
    private boolean mProfileGroupIsRemoved;

    private View mRootView;

    @Override
    public int getMetricsCategory() {
        return MetricsProto.MetricsEvent.DIALOG_BLUETOOTH_PAIRED_DEVICE_PROFILE;
    }

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

        mManager = Utils.getLocalBtManager(getActivity());
        CachedBluetoothDeviceManager deviceManager = mManager.getCachedDeviceManager();

        String address = getArguments().getString(ARG_DEVICE_ADDRESS);
        BluetoothDevice remoteDevice = mManager.getBluetoothAdapter().getRemoteDevice(address);

        mCachedDevice = deviceManager.findDevice(remoteDevice);
        if (mCachedDevice == null) {
            mCachedDevice = deviceManager.addDevice(mManager.getBluetoothAdapter(),
                    mManager.getProfileManager(), remoteDevice);
        }
        mProfileManager = mManager.getProfileManager();
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        mRootView = LayoutInflater.from(getContext()).inflate(R.layout.device_profiles_settings,
                null);
        mProfileContainer = (ViewGroup) mRootView.findViewById(R.id.profiles_section);
        mProfileLabel = (TextView) mRootView.findViewById(R.id.profiles_label);
        final EditText deviceName = (EditText) mRootView.findViewById(R.id.name);
        deviceName.setText(mCachedDevice.getName(), TextView.BufferType.EDITABLE);
        return new AlertDialog.Builder(getContext())
                .setView(mRootView)
                .setNeutralButton(R.string.forget, this)
                .setPositiveButton(R.string.okay, this)
                .setTitle(R.string.bluetooth_preference_paired_devices)
                .create();
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        switch (which) {
            case DialogInterface.BUTTON_POSITIVE:
                EditText deviceName = (EditText) mRootView.findViewById(R.id.name);
                mCachedDevice.setName(deviceName.getText().toString());
                break;
            case DialogInterface.BUTTON_NEUTRAL:
                mCachedDevice.unpair();
                break;
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mDisconnectDialog != null) {
            mDisconnectDialog.dismiss();
            mDisconnectDialog = null;
        }
        if (mCachedDevice != null) {
            mCachedDevice.unregisterCallback(this);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onResume() {
        super.onResume();

        mManager.setForegroundActivity(getActivity());
        if (mCachedDevice != null) {
            mCachedDevice.registerCallback(this);
            if (mCachedDevice.getBondState() == BluetoothDevice.BOND_NONE) {
                dismiss();
                return;
            }
            addPreferencesForProfiles();
            refresh();
        }
    }

    @Override
    public void onPause() {
        super.onPause();

        if (mCachedDevice != null) {
            mCachedDevice.unregisterCallback(this);
        }

        mManager.setForegroundActivity(null);
    }

    private void addPreferencesForProfiles() {
        mProfileContainer.removeAllViews();
        for (LocalBluetoothProfile profile : mCachedDevice.getConnectableProfiles()) {
            CheckBox pref = createProfilePreference(profile);
            // MAP and PBAP profiles would be added based on permission access
            if (!((profile instanceof PbapServerProfile) ||
                (profile instanceof MapProfile))) {
                mProfileContainer.addView(pref);
            }

            if (profile instanceof A2dpProfile) {
                BluetoothDevice device = mCachedDevice.getDevice();
                A2dpProfile a2dpProfile = (A2dpProfile) profile;
                if (a2dpProfile.supportsHighQualityAudio(device)) {
                    CheckBox highQualityPref = new CheckBox(getActivity());
                    highQualityPref.setTag(HIGH_QUALITY_AUDIO_PREF_TAG);
                    highQualityPref.setOnClickListener(v -> {
                        a2dpProfile.setHighQualityAudioEnabled(device, highQualityPref.isChecked());
                    });
                    highQualityPref.setVisibility(View.GONE);
                    mProfileContainer.addView(highQualityPref);
                }
                refreshProfilePreference(pref, profile);
            }
        }

        final int pbapPermission = mCachedDevice.getPhonebookPermissionChoice();
        Log.d(TAG, "addPreferencesForProfiles: pbapPermission = " + pbapPermission);
        // Only provide PBAP cabability if the client device has requested PBAP.
        if (pbapPermission != CachedBluetoothDevice.ACCESS_UNKNOWN) {
            final PbapServerProfile psp = mManager.getProfileManager().getPbapProfile();
            CheckBox pbapPref = createProfilePreference(psp);
            mProfileContainer.addView(pbapPref);
        }

        final MapProfile mapProfile = mManager.getProfileManager().getMapProfile();
        final int mapPermission = mCachedDevice.getMessagePermissionChoice();
        Log.d(TAG, "addPreferencesForProfiles: mapPermission = " + mapPermission);
        if (mapPermission != CachedBluetoothDevice.ACCESS_UNKNOWN) {
            CheckBox mapPreference = createProfilePreference(mapProfile);
            mProfileContainer.addView(mapPreference);
        }

        showOrHideProfileGroup();
    }

    private void showOrHideProfileGroup() {
        int numProfiles = mProfileContainer.getChildCount();
        if (!mProfileGroupIsRemoved && numProfiles == 0) {
            mProfileContainer.setVisibility(View.GONE);
            mProfileLabel.setVisibility(View.GONE);
            mProfileGroupIsRemoved = true;
        } else if (mProfileGroupIsRemoved && numProfiles != 0) {
            mProfileContainer.setVisibility(View.VISIBLE);
            mProfileLabel.setVisibility(View.VISIBLE);
            mProfileGroupIsRemoved = false;
        }
    }

    /**
     * Creates a checkbox preference for the particular profile. The key will be
     * the profile's name.
     *
     * @param profile The profile for which the preference controls.
     * @return A preference that allows the user to choose whether this profile
     *         will be connected to.
     */
    private CheckBox createProfilePreference(LocalBluetoothProfile profile) {
        CheckBox pref = new CheckBox(getActivity());
        pref.setTag(profile.toString());
        pref.setText(profile.getNameResource(mCachedDevice.getDevice()));
        pref.setOnClickListener(this);

        refreshProfilePreference(pref, profile);

        return pref;
    }

    @Override
    public void onClick(View v) {
        if (v instanceof CheckBox) {
            LocalBluetoothProfile prof = getProfileOf(v);
            onProfileClicked(prof, (CheckBox) v);
        }
    }

    private void onProfileClicked(LocalBluetoothProfile profile, CheckBox profilePref) {
        BluetoothDevice device = mCachedDevice.getDevice();

        if (!profilePref.isChecked()) {
            // Recheck it, until the dialog is done.
            profilePref.setChecked(true);
            askDisconnect(mManager.getForegroundActivity(), profile);
        } else {
            if (profile instanceof MapProfile) {
                mCachedDevice.setMessagePermissionChoice(BluetoothDevice.ACCESS_ALLOWED);
            }
            if (profile instanceof PbapServerProfile) {
                mCachedDevice.setPhonebookPermissionChoice(BluetoothDevice.ACCESS_ALLOWED);
                refreshProfilePreference(profilePref, profile);
                // PBAP server is not preffered profile and cannot initiate connection, so return
                return;
            }
            if (profile.isPreferred(device)) {
                // profile is preferred but not connected: disable auto-connect
                if (profile instanceof PanProfile) {
                    mCachedDevice.connectProfile(profile);
                } else {
                    profile.setPreferred(device, false);
                }
            } else {
                profile.setPreferred(device, true);
                mCachedDevice.connectProfile(profile);
            }
            refreshProfilePreference(profilePref, profile);
        }
    }

    private void askDisconnect(Context context,
            final LocalBluetoothProfile profile) {
        // local reference for callback
        final CachedBluetoothDevice device = mCachedDevice;
        String name = device.getName();
        if (TextUtils.isEmpty(name)) {
            name = context.getString(R.string.bluetooth_device);
        }

        String profileName = context.getString(profile.getNameResource(device.getDevice()));

        String title = context.getString(R.string.bluetooth_disable_profile_title);
        String message = context.getString(R.string.bluetooth_disable_profile_message,
                profileName, name);

        DialogInterface.OnClickListener disconnectListener =
                new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {

                // Disconnect only when user has selected OK otherwise ignore
                if (which == DialogInterface.BUTTON_POSITIVE) {
                    device.disconnect(profile);
                    profile.setPreferred(device.getDevice(), false);
                    if (profile instanceof MapProfile) {
                        device.setMessagePermissionChoice(BluetoothDevice.ACCESS_REJECTED);
                    }
                    if (profile instanceof PbapServerProfile) {
                        device.setPhonebookPermissionChoice(BluetoothDevice.ACCESS_REJECTED);
                    }
                }
                refreshProfilePreference(findProfile(profile.toString()), profile);
            }
        };

        mDisconnectDialog = Utils.showDisconnectDialog(context,
                mDisconnectDialog, disconnectListener, title, Html.fromHtml(message));
    }

    @Override
    public void onDeviceAttributesChanged() {
        refresh();
    }

    private void refresh() {
        final EditText deviceNameField = (EditText) mRootView.findViewById(R.id.name);
        if (deviceNameField != null) {
            deviceNameField.setText(mCachedDevice.getName());
            com.android.settings.Utils.setEditTextCursorPosition(deviceNameField);
        }

        refreshProfiles();
    }

    private void refreshProfiles() {
        for (LocalBluetoothProfile profile : mCachedDevice.getConnectableProfiles()) {
            CheckBox profilePref = findProfile(profile.toString());
            if (profilePref == null) {
                profilePref = createProfilePreference(profile);
                mProfileContainer.addView(profilePref);
            } else {
                refreshProfilePreference(profilePref, profile);
            }
        }
        for (LocalBluetoothProfile profile : mCachedDevice.getRemovedProfiles()) {
            CheckBox profilePref = findProfile(profile.toString());
            if (profilePref != null) {

                if (profile instanceof PbapServerProfile) {
                    final int pbapPermission = mCachedDevice.getPhonebookPermissionChoice();
                    Log.d(TAG, "refreshProfiles: pbapPermission = " + pbapPermission);
                    if (pbapPermission != CachedBluetoothDevice.ACCESS_UNKNOWN)
                        continue;
                }
                if (profile instanceof MapProfile) {
                    final int mapPermission = mCachedDevice.getMessagePermissionChoice();
                    Log.d(TAG, "refreshProfiles: mapPermission = " + mapPermission);
                    if (mapPermission != CachedBluetoothDevice.ACCESS_UNKNOWN)
                        continue;
                }
                Log.d(TAG, "Removing " + profile.toString() + " from profile list");
                mProfileContainer.removeView(profilePref);
            }
        }

        showOrHideProfileGroup();
    }

    private CheckBox findProfile(String profile) {
        return (CheckBox) mProfileContainer.findViewWithTag(profile);
    }

    private void refreshProfilePreference(CheckBox profilePref,
            LocalBluetoothProfile profile) {
        BluetoothDevice device = mCachedDevice.getDevice();

        // Gray out checkbox while connecting and disconnecting.
        profilePref.setEnabled(!mCachedDevice.isBusy());

        if (profile instanceof MapProfile) {
            profilePref.setChecked(mCachedDevice.getMessagePermissionChoice()
                    == CachedBluetoothDevice.ACCESS_ALLOWED);

        } else if (profile instanceof PbapServerProfile) {
            profilePref.setChecked(mCachedDevice.getPhonebookPermissionChoice()
                    == CachedBluetoothDevice.ACCESS_ALLOWED);

        } else if (profile instanceof PanProfile) {
            profilePref.setChecked(profile.getConnectionStatus(device) ==
                    BluetoothProfile.STATE_CONNECTED);

        } else {
            profilePref.setChecked(profile.isPreferred(device));
        }
        if (profile instanceof A2dpProfile) {
            A2dpProfile a2dpProfile = (A2dpProfile) profile;
            View v = mProfileContainer.findViewWithTag(HIGH_QUALITY_AUDIO_PREF_TAG);
            if (v instanceof CheckBox) {
                CheckBox highQualityPref = (CheckBox) v;
                highQualityPref.setText(a2dpProfile.getHighQualityAudioOptionLabel(device));
                highQualityPref.setChecked(a2dpProfile.isHighQualityAudioEnabled(device));

                if (a2dpProfile.isPreferred(device)) {
                    v.setVisibility(View.VISIBLE);
                    v.setEnabled(!mCachedDevice.isBusy());
                } else {
                    v.setVisibility(View.GONE);
                }
            }
        }
    }

    private LocalBluetoothProfile getProfileOf(View v) {
        if (!(v instanceof CheckBox)) {
            return null;
        }
        String key = (String) v.getTag();
        if (TextUtils.isEmpty(key)) return null;

        try {
            return mProfileManager.getProfileByName(key);
        } catch (IllegalArgumentException ignored) {
            return null;
        }
    }
}
