/*
 * Copyright (C) 2008 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 android.view.cts;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import android.os.SystemClock;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.PopupMenu;

import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.MediumTest;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
 * Test {@link MenuInflater}.
 */
@MediumTest
@RunWith(AndroidJUnit4.class)
public class MenuTest {
    private MenuTestActivity mActivity;
    private MenuInflater mMenuInflater;
    private Menu mMenu;

    @Rule
    public ActivityTestRule<MenuTestActivity> mActivityRule =
            new ActivityTestRule<>(MenuTestActivity.class);

    @UiThreadTest
    @Before
    public void setup() {
        mActivity = (MenuTestActivity) mActivityRule.getActivity();
        mMenuInflater = mActivity.getMenuInflater();
        mMenu = new PopupMenu(mActivity, null).getMenu();
    }

    @UiThreadTest
    @Test
    public void testPerformShortcut() {
        mMenuInflater.inflate(R.menu.shortcut_modifiers, mMenu);
        mMenu.setQwertyMode(true);
        int keyCodeToSend, metaState;
        KeyEvent keyEventToSend;

        // Test shortcut trigger in case of no modifier
        keyCodeToSend = KeyEvent.KEYCODE_A;
        metaState = KeyEvent.META_CTRL_ON;
        keyEventToSend = generateKeyEvent(keyCodeToSend, metaState);
        assertTrue(mMenu.performShortcut(keyCodeToSend, keyEventToSend, 0));
        assertEquals(mActivity.getMenuItemIdTracker(),
                mMenu.findItem(R.id.no_modifiers).getItemId());

        // Test shortcut trigger in case of default modifier
        keyCodeToSend = KeyEvent.KEYCODE_B;
        metaState = KeyEvent.META_CTRL_ON;
        keyEventToSend = generateKeyEvent(keyCodeToSend, metaState);
        assertTrue(mMenu.performShortcut(keyCodeToSend, keyEventToSend, 0));
        assertEquals(mActivity.getMenuItemIdTracker(),
                mMenu.findItem(R.id.default_modifiers).getItemId());

        // Test shortcut trigger in case of non-default single modifier
        keyCodeToSend = KeyEvent.KEYCODE_C;
        metaState = KeyEvent.META_SHIFT_ON;
        keyEventToSend = generateKeyEvent(keyCodeToSend, metaState);
        assertTrue(mMenu.performShortcut(keyCodeToSend, keyEventToSend, 0));
        assertEquals(mActivity.getMenuItemIdTracker(),
                mMenu.findItem(R.id.single_modifier).getItemId());

        // Test shortcut trigger in case of multiple modifiers
        keyCodeToSend = KeyEvent.KEYCODE_D;
        metaState = KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON;
        keyEventToSend = generateKeyEvent(keyCodeToSend, metaState);
        assertTrue(mMenu.performShortcut(keyCodeToSend, keyEventToSend, 0));
        assertEquals(mActivity.getMenuItemIdTracker(),
                mMenu.findItem(R.id.multiple_modifiers).getItemId());

        // Test no shortcut trigger in case of incorrect modifier
        keyCodeToSend = KeyEvent.KEYCODE_E;
        metaState = KeyEvent.META_CTRL_ON;
        keyEventToSend = generateKeyEvent(keyCodeToSend, metaState);
        assertFalse(mMenu.performShortcut(keyCodeToSend, keyEventToSend, 0));
    }

    @UiThreadTest
    @Test
    public void testSetShortcutWithAlpha() {
        mMenu.setQwertyMode(true);
        // Test default modifier (CTRL) when unspecified in setShortcut
        mMenu.add(0, 0, 0, "test").setShortcut('2', 'a');
        assertTrue(mMenu.isShortcutKey(KeyEvent.KEYCODE_A,
                generateKeyEvent(KeyEvent.KEYCODE_A, KeyEvent.META_CTRL_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_A,
                generateKeyEvent(KeyEvent.KEYCODE_A, KeyEvent.META_SHIFT_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_B,
                generateKeyEvent(KeyEvent.KEYCODE_B, KeyEvent.META_CTRL_ON)));
        // Test setShortcut with modifier
        mMenu.add(0, 0, 0, "test").setShortcut('3', 'b',
                KeyEvent.META_ALT_ON, KeyEvent.META_ALT_ON);
        assertTrue(mMenu.isShortcutKey(KeyEvent.KEYCODE_B,
                generateKeyEvent(KeyEvent.KEYCODE_B, KeyEvent.META_ALT_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_B,
                generateKeyEvent(KeyEvent.KEYCODE_B, KeyEvent.META_CTRL_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_C,
                generateKeyEvent(KeyEvent.KEYCODE_C, KeyEvent.META_ALT_ON)));
    }

    @UiThreadTest
    @Test
    public void testSetShortcutWithNumeric() {
        mMenu.setQwertyMode(false);
        // Test default modifier (CTRL) when unspecified in setShortcut
        mMenu.add(0, 0, 0, "test").setShortcut('2', 'a');
        assertTrue(mMenu.isShortcutKey(KeyEvent.KEYCODE_2,
                generateKeyEvent(KeyEvent.KEYCODE_2, KeyEvent.META_CTRL_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_2,
                generateKeyEvent(KeyEvent.KEYCODE_2, KeyEvent.META_ALT_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_3,
                generateKeyEvent(KeyEvent.KEYCODE_3, KeyEvent.META_CTRL_ON)));
        // Test setShortcut with modifier
        mMenu.add(0, 0, 0, "test").setShortcut('3', 'b',
                KeyEvent.META_ALT_ON, KeyEvent.META_ALT_ON);
        assertTrue(mMenu.isShortcutKey(KeyEvent.KEYCODE_3,
                generateKeyEvent(KeyEvent.KEYCODE_3, KeyEvent.META_ALT_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_3,
                generateKeyEvent(KeyEvent.KEYCODE_3, KeyEvent.META_CTRL_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_4,
                generateKeyEvent(KeyEvent.KEYCODE_4, KeyEvent.META_ALT_ON)));
    }

    @UiThreadTest
    @Test
    public void testSetAlphabeticShortcut() {
        mMenu.setQwertyMode(true);
        // Test default modifier when unspecified in setAlphabeticShortcut
        mMenu.add(0, 0, 0, "test").setAlphabeticShortcut('a');
        assertTrue(mMenu.isShortcutKey(KeyEvent.KEYCODE_A,
                generateKeyEvent(KeyEvent.KEYCODE_A, KeyEvent.META_CTRL_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_A,
                generateKeyEvent(KeyEvent.KEYCODE_A, KeyEvent.META_SHIFT_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_B,
                generateKeyEvent(KeyEvent.KEYCODE_B, KeyEvent.META_CTRL_ON)));
        // Test setAlphabeticShortcut with single modifier
        mMenu.add(0, 0, 0, "test").setAlphabeticShortcut('b', KeyEvent.META_ALT_ON);
        assertTrue(mMenu.isShortcutKey(KeyEvent.KEYCODE_B,
                generateKeyEvent(KeyEvent.KEYCODE_B, KeyEvent.META_ALT_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_B,
                generateKeyEvent(KeyEvent.KEYCODE_B, KeyEvent.META_CTRL_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_C,
                generateKeyEvent(KeyEvent.KEYCODE_C, KeyEvent.META_ALT_ON)));
        // Test setAlphabeticShortcut with multiple modifiers
        mMenu.add(0, 0, 0, "test").setAlphabeticShortcut('c',
                KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON);
        assertTrue(mMenu.isShortcutKey(KeyEvent.KEYCODE_C, generateKeyEvent(KeyEvent.KEYCODE_C,
                KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_C, generateKeyEvent(KeyEvent.KEYCODE_C,
                KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_D, generateKeyEvent(KeyEvent.KEYCODE_D,
                KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON)));
    }

    @UiThreadTest
    @Test
    public void testSetNumericShortcut() {
        mMenu.setQwertyMode(false);
        // Test default modifier when unspecified in setNumericShortcut
        mMenu.add(0, 0, 0, "test").setNumericShortcut('2');
        assertTrue(mMenu.isShortcutKey(KeyEvent.KEYCODE_2,
                generateKeyEvent(KeyEvent.KEYCODE_2, KeyEvent.META_CTRL_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_2,
                generateKeyEvent(KeyEvent.KEYCODE_2, KeyEvent.META_ALT_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_3,
                generateKeyEvent(KeyEvent.KEYCODE_3, KeyEvent.META_CTRL_ON)));
        // Test setNumericShortcut with single modifier
        mMenu.add(0, 0, 0, "test").setNumericShortcut('3', KeyEvent.META_ALT_ON);
        assertTrue(mMenu.isShortcutKey(KeyEvent.KEYCODE_3,
                generateKeyEvent(KeyEvent.KEYCODE_3, KeyEvent.META_ALT_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_3,
                generateKeyEvent(KeyEvent.KEYCODE_3, KeyEvent.META_CTRL_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_4,
                generateKeyEvent(KeyEvent.KEYCODE_4, KeyEvent.META_ALT_ON)));
        // Test setNumericShortcut with multiple modifiers
        mMenu.add(0, 0, 0, "test").setNumericShortcut('4',
                KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON);
        assertTrue(mMenu.isShortcutKey(KeyEvent.KEYCODE_4, generateKeyEvent(KeyEvent.KEYCODE_4,
                KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_4, generateKeyEvent(KeyEvent.KEYCODE_4,
                KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON)));
        assertFalse(mMenu.isShortcutKey(KeyEvent.KEYCODE_5, generateKeyEvent(KeyEvent.KEYCODE_5,
                KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON)));
    }

    @UiThreadTest
    @Test
    public void testGetShortcutModifiers() {
        MenuItem item = mMenu.add(0, 0, 0, "test");
        // Test shortcut getters and setters
        item.setShortcut('2', 'a', KeyEvent.META_ALT_ON,
                KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON);
        assertEquals('2', item.getNumericShortcut());
        assertEquals(KeyEvent.META_ALT_ON, item.getNumericModifiers());
        assertEquals('a', item.getAlphabeticShortcut());
        assertEquals(KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON, item.getAlphabeticModifiers());
    }

    @UiThreadTest
    @Test
    public void testIsShortcutWithBackspace() {
        mMenu.setQwertyMode(true);
        mMenu.add(0, 0, 0, "test").setShortcut('2', '\b');
        assertTrue(mMenu.isShortcutKey(KeyEvent.KEYCODE_DEL,
                generateKeyEvent(KeyEvent.KEYCODE_DEL, KeyEvent.META_CTRL_ON)));
    }

    @UiThreadTest
    @Test
    public void testIsShortcutWithNewline() {
        mMenu.setQwertyMode(true);
        mMenu.add(0, 0, 0, "test").setShortcut('2', '\n');
        assertTrue(mMenu.isShortcutKey(KeyEvent.KEYCODE_ENTER,
                generateKeyEvent(KeyEvent.KEYCODE_ENTER, KeyEvent.META_CTRL_ON)));
    }

    private static KeyEvent generateKeyEvent(int keyCodeToSend, int metaState) {
        long downTime = SystemClock.uptimeMillis();
        return new KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN, keyCodeToSend, 0, metaState);
    }
}
