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

import static com.android.settings.gestures.PowerMenuSettingsUtils.LONG_PRESS_POWER_ASSISTANT_VALUE;
import static com.android.settings.gestures.PowerMenuSettingsUtils.LONG_PRESS_POWER_GLOBAL_ACTIONS;
import static com.android.settings.gestures.PowerMenuSettingsUtils.POWER_BUTTON_LONG_PRESS_DEFAULT_VALUE_RESOURCE;
import static com.android.settings.gestures.PowerMenuSettingsUtils.POWER_BUTTON_LONG_PRESS_SETTING;

import android.content.Context;
import android.provider.Settings;

import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;

import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;

import org.checkerframework.checker.nullness.qual.MonotonicNonNull;

/**
 * Configures the behaviour of long press power button action.
 */
public class LongPressPowerButtonPreferenceController extends TogglePreferenceController {

    private static final String KEY_CHORD_POWER_VOLUME_UP_SETTING =
            Settings.Global.KEY_CHORD_POWER_VOLUME_UP;

    private static final String FOOTER_HINT_KEY = "power_menu_power_volume_up_hint";
    private static final String ASSIST_SWITCH_KEY = "gesture_power_menu_long_press_for_assist";

    /**
     * Values used for volume key chord behaviour when Assist setting is enabled.
     *
     * Values based on config_keyChordPowerVolumeUp in
     * frameworks/base/core/res/res/values/config.xml
     */
    @VisibleForTesting
    static final int KEY_CHORD_POWER_VOLUME_UP_NO_ACTION = 0;
    @VisibleForTesting
    static final int KEY_CHORD_POWER_VOLUME_UP_MUTE_TOGGLE = 1;
    @VisibleForTesting
    static final int KEY_CHORD_POWER_VOLUME_UP_GLOBAL_ACTIONS = 2;

    private static final int KEY_CHORD_POWER_VOLUME_UP_DEFAULT_VALUE_RESOURCE =
            com.android.internal.R.integer.config_keyChordPowerVolumeUp;

    @MonotonicNonNull
    @VisibleForTesting
    Preference mFooterHint;

    @MonotonicNonNull
    @VisibleForTesting
    Preference mAssistSwitch;

    public LongPressPowerButtonPreferenceController(Context context, String key) {
        super(context, key);
    }

    @Override
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        mFooterHint = screen.findPreference(FOOTER_HINT_KEY);
        mAssistSwitch = screen.findPreference(ASSIST_SWITCH_KEY);
        refreshStateDisplay();
    }

    @Override
    public CharSequence getSummary() {
        final int powerButtonValue = PowerMenuSettingsUtils.getPowerButtonSettingValue(mContext);
        if (powerButtonValue == LONG_PRESS_POWER_ASSISTANT_VALUE) {
            return mContext.getString(R.string.power_menu_summary_long_press_for_assist_enabled);
        } else if (powerButtonValue == LONG_PRESS_POWER_GLOBAL_ACTIONS) {
            return mContext.getString(
                    R.string.power_menu_summary_long_press_for_assist_disabled_with_power_menu);
        } else {
            return mContext.getString(
                    R.string.power_menu_summary_long_press_for_assist_disabled_no_action);
        }
    }

    @Override
    public int getAvailabilityStatus() {
        final boolean enabled = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable);
        return enabled ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
    }

    @Override
    public boolean isChecked() {
        return PowerMenuSettingsUtils.isLongPressPowerForAssistEnabled(mContext);
    }

    @Override
    public boolean setChecked(boolean isChecked) {
        if (setPowerLongPressValue(isChecked)) {
            // The key chord value is dependant on the long press setting and it always
            // toggled in tandem. POWER_BUTTON_LONG_PRESS_SETTING is always the source
            // of truth for both.
            setPowerVolumeChordValue(isChecked);
            refreshStateDisplay();
            return true;
        }

        return false;
    }

    @Override
    public int getSliceHighlightMenuRes() {
        return R.string.menu_key_system;
    }

    private void refreshStateDisplay() {
        if (mAssistSwitch != null) {
            mAssistSwitch.setSummary(getSummary());
        }

        if (mFooterHint != null) {
            String footerHintText = mContext.getString(R.string.power_menu_power_volume_up_hint);
            // If the device supports hush gesture, we need to notify the user where to find
            // the setting.
            if (mContext.getResources().getBoolean(
                    com.android.internal.R.bool.config_volumeHushGestureEnabled)) {
                footerHintText = footerHintText + "\n\n" + mContext.getString(
                        R.string.power_menu_power_prevent_ringing_hint);
            }

            mFooterHint.setSummary(footerHintText);
            mFooterHint.setVisible(isPowerMenuKeyChordEnabled(mContext));
        }
    }

    private static boolean isPowerMenuKeyChordEnabled(Context context) {
        return Settings.Global.getInt(context.getContentResolver(),
                KEY_CHORD_POWER_VOLUME_UP_SETTING,
                context.getResources().getInteger(
                        com.android.internal.R.integer.config_keyChordPowerVolumeUp))
                == KEY_CHORD_POWER_VOLUME_UP_GLOBAL_ACTIONS;
    }

    private boolean setPowerLongPressValue(boolean isChecked) {
        if (isChecked) {
            return Settings.Global.putInt(mContext.getContentResolver(),
                    POWER_BUTTON_LONG_PRESS_SETTING, LONG_PRESS_POWER_ASSISTANT_VALUE);
        }

        // We need to determine the right disabled value based on the device default
        // for long-press power.

        // If the default is to start the assistant, then the fallback is GlobalActions.
        final int defaultPowerButtonValue = mContext.getResources().getInteger(
                POWER_BUTTON_LONG_PRESS_DEFAULT_VALUE_RESOURCE);
        if (defaultPowerButtonValue == LONG_PRESS_POWER_ASSISTANT_VALUE) {
            return Settings.Global.putInt(mContext.getContentResolver(),
                    POWER_BUTTON_LONG_PRESS_SETTING, LONG_PRESS_POWER_GLOBAL_ACTIONS);
        }

        // If the default is something different than Assist, we use that default.
        return Settings.Global.putInt(mContext.getContentResolver(),
                POWER_BUTTON_LONG_PRESS_SETTING, defaultPowerButtonValue);
    }

    /**
     * Updates {@link Settings.Global.KEY_CHORD_POWER_VOLUME_UP} based on the changed value of
     * {@link #POWER_BUTTON_LONG_PRESS_SETTING}. If power button is used for Assist, key chord
     * should show the power menu.
     */
    private boolean setPowerVolumeChordValue(boolean isPowerButtonLongPressChecked) {
        if (isPowerButtonLongPressChecked) {
            return Settings.Global.putInt(mContext.getContentResolver(),
                    KEY_CHORD_POWER_VOLUME_UP_SETTING, KEY_CHORD_POWER_VOLUME_UP_GLOBAL_ACTIONS);
        }

        // We restore key chord to the default value.
        int keyChordDefaultValue = mContext.getResources().getInteger(
                KEY_CHORD_POWER_VOLUME_UP_DEFAULT_VALUE_RESOURCE);
        return Settings.Global.putInt(mContext.getContentResolver(),
                KEY_CHORD_POWER_VOLUME_UP_SETTING, keyChordDefaultValue);
    }

}
