// Copyright (C) 2023 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.

// This module provides hotkey detection using type-safe human-readable strings.
//
// The basic premise is this: Let's say you have a KeyboardEvent |event|, and
// you wanted to check whether it contains the hotkey 'Ctrl+O', you can execute
// the following function:
//
//   checkHotkey('Shift+O', event);
//
// ...which will evaluate to true if 'Shift+O' is discovered in the event.
//
// This will only trigger when O is pressed while the Shift key is held, not O
// on it's own, and not if other modifiers such as Alt or Ctrl were also held.
//
// Modifiers include 'Shift', 'Ctrl', 'Alt', and 'Mod':
// - 'Shift' and 'Ctrl' are fairly self explanatory.
// - 'Alt' is 'option' on Macs.
// - 'Mod' is a special modifier which means 'Ctrl' on PC and 'Cmd' on Mac.
// Modifiers may be combined in various ways - check the |Modifier| type.
//
// By default hotkeys will not register when the event target is inside an
// editable element, such as <textarea> and some <input>s.
// Prefixing a hotkey with a bang '!' relaxes is requirement, meaning the hotkey
// will register inside editable fields.

// E.g. '!Mod+Shift+P' will register when pressed when a text box has focus but
// 'Mod+Shift+P' (no bang) will not.
// Warning: Be careful using this with single key hotkeys, e.g. '!P' is usually
// never what you want!
//
// Some single-key hotkeys like '?' and '!' normally cannot be activated in
// without also pressing shift key, so the shift requirement is relaxed for
// these keys.

import {elementIsEditable} from './dom_utils';
import {Optional} from './utils';

type Alphabet =
  | 'A'
  | 'B'
  | 'C'
  | 'D'
  | 'E'
  | 'F'
  | 'G'
  | 'H'
  | 'I'
  | 'J'
  | 'K'
  | 'L'
  | 'M'
  | 'N'
  | 'O'
  | 'P'
  | 'Q'
  | 'R'
  | 'S'
  | 'T'
  | 'U'
  | 'V'
  | 'W'
  | 'X'
  | 'Y'
  | 'Z';
type Number = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
type Special =
  | 'Enter'
  | 'Escape'
  | 'Delete'
  | '/'
  | '?'
  | '!'
  | 'Space'
  | 'ArrowUp'
  | 'ArrowDown'
  | 'ArrowLeft'
  | 'ArrowRight'
  | '['
  | ']';
export type Key = Alphabet | Number | Special;
export type Modifier =
  | ''
  | 'Mod+'
  | 'Shift+'
  | 'Ctrl+'
  | 'Alt+'
  | 'Mod+Shift+'
  | 'Mod+Alt+'
  | 'Mod+Shift+Alt+'
  | 'Ctrl+Shift+'
  | 'Ctrl+Alt'
  | 'Ctrl+Shift+Alt';
type AllowInEditable = '!' | '';
export type Hotkey = `${AllowInEditable}${Modifier}${Key}`;

// The following list of keys cannot be pressed wither with or without the
// presence of the Shift modifier on most keyboard layouts. Thus we should
// ignore shift in these cases.
const shiftExceptions = [
  '0',
  '1',
  '2',
  '3',
  '4',
  '5',
  '6',
  '7',
  '8',
  '9',
  '/',
  '?',
  '!',
  '[',
  ']',
];

const macModifierStrings: ReadonlyMap<Modifier, string> = new Map<
  Modifier,
  string
>([
  ['', ''],
  ['Mod+', '⌘'],
  ['Shift+', '⇧'],
  ['Ctrl+', '⌃'],
  ['Alt+', '⌥'],
  ['Mod+Shift+', '⌘⇧'],
  ['Mod+Alt+', '⌘⌥'],
  ['Mod+Shift+Alt+', '⌘⇧⌥'],
  ['Ctrl+Shift+', '⌃⇧'],
  ['Ctrl+Alt', '⌃⌥'],
  ['Ctrl+Shift+Alt', '⌃⇧⌥'],
]);

const pcModifierStrings: ReadonlyMap<Modifier, string> = new Map<
  Modifier,
  string
>([
  ['', ''],
  ['Mod+', 'Ctrl+'],
  ['Mod+Shift+', 'Ctrl+Shift+'],
  ['Mod+Alt+', 'Ctrl+Alt+'],
  ['Mod+Shift+Alt+', 'Ctrl+Shift+Alt+'],
]);

// Represents a deconstructed hotkey.
export interface HotkeyParts {
  // The name of the primary key of this hotkey.
  key: Key;

  // All the modifiers as one chunk. E.g. 'Mod+Shift+'.
  modifier: Modifier;

  // Whether this hotkey should register when the event target is inside an
  // editable field.
  allowInEditable: boolean;
}

// Deconstruct a hotkey from its string representation into its constituent
// parts.
export function parseHotkey(hotkey: Hotkey): Optional<HotkeyParts> {
  const regex = /^(!?)((?:Mod\+|Shift\+|Alt\+|Ctrl\+)*)(.*)$/;
  const result = hotkey.match(regex);

  if (!result) {
    return undefined;
  }

  return {
    allowInEditable: result[1] === '!',
    modifier: result[2] as Modifier,
    key: result[3] as Key,
  };
}

// Print the hotkey in a human readable format.
export function formatHotkey(
  hotkey: Hotkey,
  spoof?: Platform,
): Optional<string> {
  const parsed = parseHotkey(hotkey);
  return parsed && formatHotkeyParts(parsed, spoof);
}

function formatHotkeyParts(
  {modifier, key}: HotkeyParts,
  spoof?: Platform,
): string {
  return `${formatModifier(modifier, spoof)}${key}`;
}

function formatModifier(modifier: Modifier, spoof?: Platform): string {
  const platform = spoof || getPlatform();
  const strings = platform === 'Mac' ? macModifierStrings : pcModifierStrings;
  return strings.get(modifier) ?? modifier;
}

// Like |KeyboardEvent| but all fields apart from |key| are optional.
export type KeyboardEventLike = Pick<KeyboardEvent, 'key'> &
  Partial<KeyboardEvent>;

// Check whether |hotkey| is present in the keyboard event |event|.
export function checkHotkey(
  hotkey: Hotkey,
  event: KeyboardEventLike,
  spoofPlatform?: Platform,
): boolean {
  const result = parseHotkey(hotkey);
  if (!result) {
    return false;
  }

  const {key, allowInEditable} = result;
  const {target = null} = event;

  const inEditable = elementIsEditable(target);
  if (inEditable && !allowInEditable) {
    return false;
  }
  return compareKeys(event, key) && checkMods(event, result, spoofPlatform);
}

// Return true if |key| matches the event's key.
function compareKeys(e: KeyboardEventLike, key: Key): boolean {
  return e.key.toLowerCase() === key.toLowerCase();
}

// Return true if modifiers specified in |mods| match those in the event.
function checkMods(
  event: KeyboardEventLike,
  hotkey: HotkeyParts,
  spoofPlatform?: Platform,
): boolean {
  const platform = spoofPlatform ?? getPlatform();

  const {key, modifier} = hotkey;

  const {
    ctrlKey = false,
    altKey = false,
    shiftKey = false,
    metaKey = false,
  } = event;

  const wantShift = modifier.includes('Shift');
  const wantAlt = modifier.includes('Alt');
  const wantCtrl =
    platform === 'Mac'
      ? modifier.includes('Ctrl')
      : modifier.includes('Ctrl') || modifier.includes('Mod');
  const wantMeta = platform === 'Mac' && modifier.includes('Mod');

  // For certain keys we relax the shift requirement, as they usually cannot be
  // pressed without the shift key on English keyboards.
  const shiftOk =
    shiftExceptions.includes(key as string) || shiftKey === wantShift;

  return (
    metaKey === wantMeta &&
    Boolean(shiftOk) &&
    altKey === wantAlt &&
    ctrlKey === wantCtrl
  );
}

export type Platform = 'Mac' | 'PC';

// Get the current platform (PC or Mac).
export function getPlatform(): Platform {
  return window.navigator.platform.indexOf('Mac') !== -1 ? 'Mac' : 'PC';
}
