/*
 * Copyright (C) 2014 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.systemui.qs.tiles;

import android.annotation.Nullable;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.provider.Settings;
import android.service.quicksettings.Tile;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Switch;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.Utils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.graph.BluetoothDeviceLayerDrawable;
import com.android.systemui.R;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
import com.android.systemui.qs.QSDetailItems;
import com.android.systemui.qs.QSDetailItems.Item;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.BluetoothController;

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

import javax.inject.Inject;

/** Quick settings tile: Bluetooth **/
public class BluetoothTile extends QSTileImpl<BooleanState> {
    private static final Intent BLUETOOTH_SETTINGS = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);

    private final BluetoothController mController;
    private final BluetoothDetailAdapter mDetailAdapter;
    private final ActivityStarter mActivityStarter;

    @Inject
    public BluetoothTile(QSHost host,
            BluetoothController bluetoothController,
            ActivityStarter activityStarter) {
        super(host);
        mController = bluetoothController;
        mActivityStarter = activityStarter;
        mDetailAdapter = (BluetoothDetailAdapter) createDetailAdapter();
        mController.observe(getLifecycle(), mCallback);
    }

    @Override
    public DetailAdapter getDetailAdapter() {
        return mDetailAdapter;
    }

    @Override
    public BooleanState newTileState() {
        return new BooleanState();
    }

    @Override
    protected void handleClick() {
        // Secondary clicks are header clicks, just toggle.
        final boolean isEnabled = mState.value;
        // Immediately enter transient enabling state when turning bluetooth on.
        refreshState(isEnabled ? null : ARG_SHOW_TRANSIENT_ENABLING);
        mController.setBluetoothEnabled(!isEnabled);
    }

    @Override
    public Intent getLongClickIntent() {
        return new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
    }

    @Override
    protected void handleSecondaryClick() {
        if (!mController.canConfigBluetooth()) {
            mActivityStarter.postStartActivityDismissingKeyguard(
                    new Intent(Settings.ACTION_BLUETOOTH_SETTINGS), 0);
            return;
        }
        showDetail(true);
        if (!mState.value) {
            mController.setBluetoothEnabled(true);
        }
    }

    @Override
    public CharSequence getTileLabel() {
        return mContext.getString(R.string.quick_settings_bluetooth_label);
    }

    @Override
    protected void handleUpdateState(BooleanState state, Object arg) {
        final boolean transientEnabling = arg == ARG_SHOW_TRANSIENT_ENABLING;
        final boolean enabled = transientEnabling || mController.isBluetoothEnabled();
        final boolean connected = mController.isBluetoothConnected();
        final boolean connecting = mController.isBluetoothConnecting();
        state.isTransient = transientEnabling || connecting ||
                mController.getBluetoothState() == BluetoothAdapter.STATE_TURNING_ON;
        state.dualTarget = true;
        state.value = enabled;
        if (state.slash == null) {
            state.slash = new SlashState();
        }
        state.slash.isSlashed = !enabled;
        state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
        state.secondaryLabel = TextUtils.emptyIfNull(
                getSecondaryLabel(enabled, connecting, connected, state.isTransient));
        state.contentDescription = state.label;
        state.stateDescription = "";
        if (enabled) {
            if (connected) {
                state.icon = new BluetoothConnectedTileIcon();
                if (!TextUtils.isEmpty(mController.getConnectedDeviceName())) {
                    state.label = mController.getConnectedDeviceName();
                }
                state.stateDescription =
                        mContext.getString(R.string.accessibility_bluetooth_name, state.label)
                                + ", " + state.secondaryLabel;
            } else if (state.isTransient) {
                state.icon = ResourceIcon.get(
                        com.android.internal.R.drawable.ic_bluetooth_transient_animation);
                state.stateDescription = state.secondaryLabel;
            } else {
                state.icon =
                        ResourceIcon.get(com.android.internal.R.drawable.ic_qs_bluetooth);
                state.contentDescription = mContext.getString(
                        R.string.accessibility_quick_settings_bluetooth);
                state.stateDescription = mContext.getString(R.string.accessibility_not_connected);
            }
            state.state = Tile.STATE_ACTIVE;
        } else {
            state.icon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_bluetooth);
            state.contentDescription = mContext.getString(
                    R.string.accessibility_quick_settings_bluetooth);
            state.state = Tile.STATE_INACTIVE;
        }

        state.dualLabelContentDescription = mContext.getResources().getString(
                R.string.accessibility_quick_settings_open_settings, getTileLabel());
        state.expandedAccessibilityClassName = Switch.class.getName();
    }

    /**
     * Returns the secondary label to use for the given bluetooth connection in the form of the
     * battery level or bluetooth profile name. If the bluetooth is disabled, there's no connected
     * devices, or we can't map the bluetooth class to a profile, this instead returns {@code null}.
     * @param enabled whether bluetooth is enabled
     * @param connecting whether bluetooth is connecting to a device
     * @param connected whether there's a device connected via bluetooth
     * @param isTransient whether bluetooth is currently in a transient state turning on
     */
    @Nullable
    private String getSecondaryLabel(boolean enabled, boolean connecting, boolean connected,
            boolean isTransient) {
        if (connecting) {
            return mContext.getString(R.string.quick_settings_connecting);
        }
        if (isTransient) {
            return mContext.getString(R.string.quick_settings_bluetooth_secondary_label_transient);
        }

        List<CachedBluetoothDevice> connectedDevices = mController.getConnectedDevices();
        if (enabled && connected && !connectedDevices.isEmpty()) {
            if (connectedDevices.size() > 1) {
                // TODO(b/76102598): add a new string for "X connected devices" after P
                return mContext.getResources().getQuantityString(
                        R.plurals.quick_settings_hotspot_secondary_label_num_devices,
                        connectedDevices.size(),
                        connectedDevices.size());
            }

            CachedBluetoothDevice lastDevice = connectedDevices.get(0);
            final int batteryLevel = lastDevice.getBatteryLevel();

            if (batteryLevel > BluetoothDevice.BATTERY_LEVEL_UNKNOWN) {
                return mContext.getString(
                        R.string.quick_settings_bluetooth_secondary_label_battery_level,
                        Utils.formatPercentage(batteryLevel));

            } else {
                final BluetoothClass bluetoothClass = lastDevice.getBtClass();
                if (bluetoothClass != null) {
                    if (lastDevice.isHearingAidDevice()) {
                        return mContext.getString(
                                R.string.quick_settings_bluetooth_secondary_label_hearing_aids);
                    } else if (bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_A2DP)) {
                        return mContext.getString(
                                R.string.quick_settings_bluetooth_secondary_label_audio);
                    } else if (bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET)) {
                        return mContext.getString(
                                R.string.quick_settings_bluetooth_secondary_label_headset);
                    } else if (bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_HID)) {
                        return mContext.getString(
                                R.string.quick_settings_bluetooth_secondary_label_input);
                    }
                }
            }
        }

        return null;
    }

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

    @Override
    protected String composeChangeAnnouncement() {
        if (mState.value) {
            return mContext.getString(R.string.accessibility_quick_settings_bluetooth_changed_on);
        } else {
            return mContext.getString(R.string.accessibility_quick_settings_bluetooth_changed_off);
        }
    }

    @Override
    public boolean isAvailable() {
        return mController.isBluetoothSupported();
    }

    private final BluetoothController.Callback mCallback = new BluetoothController.Callback() {
        @Override
        public void onBluetoothStateChange(boolean enabled) {
            refreshState();
            if (isShowingDetail()) {
                mDetailAdapter.updateItems();
                fireToggleStateChanged(mDetailAdapter.getToggleState());
            }
        }

        @Override
        public void onBluetoothDevicesChanged() {
            refreshState();
            if (isShowingDetail()) {
                mDetailAdapter.updateItems();
            }
        }
    };

    @Override
    protected DetailAdapter createDetailAdapter() {
        return new BluetoothDetailAdapter();
    }

    /**
     * Bluetooth icon wrapper for Quick Settings with a battery indicator that reflects the
     * connected device's battery level. This is used instead of
     * {@link com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIcon} in order to use a context
     * that reflects dark/light theme attributes.
     */
    private class BluetoothBatteryTileIcon extends Icon {
        private int mBatteryLevel;
        private float mIconScale;

        BluetoothBatteryTileIcon(int batteryLevel, float iconScale) {
            mBatteryLevel = batteryLevel;
            mIconScale = iconScale;
        }

        @Override
        public Drawable getDrawable(Context context) {
            // This method returns Pair<Drawable, String> while first value is the drawable
            return BluetoothDeviceLayerDrawable.createLayerDrawable(
                    context,
                    R.drawable.ic_bluetooth_connected,
                    mBatteryLevel,
                    mIconScale);
        }
    }


    /**
     * Bluetooth icon wrapper (when connected with no battery indicator) for Quick Settings. This is
     * used instead of {@link com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIcon} in order to
     * use a context that reflects dark/light theme attributes.
     */
    private class BluetoothConnectedTileIcon extends Icon {

        BluetoothConnectedTileIcon() {
            // Do nothing. Default constructor to limit visibility.
        }

        @Override
        public Drawable getDrawable(Context context) {
            // This method returns Pair<Drawable, String> - the first value is the drawable.
            return context.getDrawable(R.drawable.ic_bluetooth_connected);
        }
    }

    protected class BluetoothDetailAdapter implements DetailAdapter, QSDetailItems.Callback {
        // We probably won't ever have space in the UI for more than 20 devices, so don't
        // get info for them.
        private static final int MAX_DEVICES = 20;
        private QSDetailItems mItems;

        @Override
        public CharSequence getTitle() {
            return mContext.getString(R.string.quick_settings_bluetooth_label);
        }

        @Override
        public Boolean getToggleState() {
            return mState.value;
        }

        @Override
        public boolean getToggleEnabled() {
            return mController.getBluetoothState() == BluetoothAdapter.STATE_OFF
                    || mController.getBluetoothState() == BluetoothAdapter.STATE_ON;
        }

        @Override
        public Intent getSettingsIntent() {
            return BLUETOOTH_SETTINGS;
        }

        @Override
        public void setToggleState(boolean state) {
            MetricsLogger.action(mContext, MetricsEvent.QS_BLUETOOTH_TOGGLE, state);
            mController.setBluetoothEnabled(state);
        }

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

        @Override
        public View createDetailView(Context context, View convertView, ViewGroup parent) {
            mItems = QSDetailItems.convertOrInflate(context, convertView, parent);
            mItems.setTagSuffix("Bluetooth");
            mItems.setCallback(this);
            updateItems();
            setItemsVisible(mState.value);
            return mItems;
        }

        public void setItemsVisible(boolean visible) {
            if (mItems == null) return;
            mItems.setItemsVisible(visible);
        }

        private void updateItems() {
            if (mItems == null) return;
            if (mController.isBluetoothEnabled()) {
                mItems.setEmptyState(R.drawable.ic_qs_bluetooth_detail_empty,
                        R.string.quick_settings_bluetooth_detail_empty_text);
            } else {
                mItems.setEmptyState(R.drawable.ic_qs_bluetooth_detail_empty,
                        R.string.bt_is_off);
            }
            ArrayList<Item> items = new ArrayList<Item>();
            final Collection<CachedBluetoothDevice> devices = mController.getDevices();
            if (devices != null) {
                int connectedDevices = 0;
                int count = 0;
                for (CachedBluetoothDevice device : devices) {
                    if (mController.getBondState(device) == BluetoothDevice.BOND_NONE) continue;
                    final Item item = new Item();
                    item.iconResId = com.android.internal.R.drawable.ic_qs_bluetooth;
                    item.line1 = device.getName();
                    item.tag = device;
                    int state = device.getMaxConnectionState();
                    if (state == BluetoothProfile.STATE_CONNECTED) {
                        item.iconResId = R.drawable.ic_bluetooth_connected;
                        int batteryLevel = device.getBatteryLevel();
                        if (batteryLevel > BluetoothDevice.BATTERY_LEVEL_UNKNOWN) {
                            item.icon = new BluetoothBatteryTileIcon(batteryLevel,1 /* iconScale */);
                            item.line2 = mContext.getString(
                                    R.string.quick_settings_connected_battery_level,
                                    Utils.formatPercentage(batteryLevel));
                        } else {
                            item.line2 = mContext.getString(R.string.quick_settings_connected);
                        }
                        item.canDisconnect = true;
                        items.add(connectedDevices, item);
                        connectedDevices++;
                    } else if (state == BluetoothProfile.STATE_CONNECTING) {
                        item.iconResId = R.drawable.ic_qs_bluetooth_connecting;
                        item.line2 = mContext.getString(R.string.quick_settings_connecting);
                        items.add(connectedDevices, item);
                    } else {
                        items.add(item);
                    }
                    if (++count == MAX_DEVICES) {
                        break;
                    }
                }
            }
            mItems.setItems(items.toArray(new Item[items.size()]));
        }

        @Override
        public void onDetailItemClick(Item item) {
            if (item == null || item.tag == null) return;
            final CachedBluetoothDevice device = (CachedBluetoothDevice) item.tag;
            if (device != null && device.getMaxConnectionState()
                    == BluetoothProfile.STATE_DISCONNECTED) {
                mController.connect(device);
            }
        }

        @Override
        public void onDetailItemDisconnect(Item item) {
            if (item == null || item.tag == null) return;
            final CachedBluetoothDevice device = (CachedBluetoothDevice) item.tag;
            if (device != null) {
                mController.disconnect(device);
            }
        }
    }
}
