/** @file
  Provides a way for 3rd party applications to register themselves for launch by the
  Boot Manager based on hot key

Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "Hotkey.h"


LIST_ENTRY        mHotkeyList = INITIALIZE_LIST_HEAD_VARIABLE (mHotkeyList);
BDS_COMMON_OPTION *mHotkeyBootOption = NULL;
EFI_EVENT         mHotkeyEvent;
VOID              *mHotkeyRegistration;


/**
  Check if the Key Option is valid or not.

  @param KeyOption       The Hot Key Option to be checked.

  @retval  TRUE          The Hot Key Option is valid.
  @retval  FALSE         The Hot Key Option is invalid.

**/
BOOLEAN
IsKeyOptionValid (
  IN EFI_KEY_OPTION     *KeyOption
)
{
  UINT16   BootOptionName[10];
  UINT8    *BootOptionVar;
  UINTN    BootOptionSize;
  UINT32   Crc;

  //
  // Check whether corresponding Boot Option exist
  //
  UnicodeSPrint (BootOptionName, sizeof (BootOptionName), L"Boot%04x", KeyOption->BootOption);
  BootOptionVar = BdsLibGetVariableAndSize (
                    BootOptionName,
                    &gEfiGlobalVariableGuid,
                    &BootOptionSize
                    );

  if (BootOptionVar == NULL || BootOptionSize == 0) {
    return FALSE;
  }

  //
  // Check CRC for Boot Option
  //
  gBS->CalculateCrc32 (BootOptionVar, BootOptionSize, &Crc);
  FreePool (BootOptionVar);

  return (BOOLEAN) ((KeyOption->BootOptionCrc == Crc) ? TRUE : FALSE);
}

/**
  Try to boot the boot option triggered by hotkey.
  @retval  EFI_SUCCESS             There is HotkeyBootOption & it is processed
  @retval  EFI_NOT_FOUND           There is no HotkeyBootOption
**/
EFI_STATUS
HotkeyBoot (
  VOID
  )
{ 
  EFI_STATUS           Status;
  UINTN                ExitDataSize;
  CHAR16               *ExitData;

  if (mHotkeyBootOption == NULL) {
    return EFI_NOT_FOUND;
  } 
  
  BdsLibConnectDevicePath (mHotkeyBootOption->DevicePath);

  //
  // Clear the screen before launch this BootOption
  //
  gST->ConOut->Reset (gST->ConOut, FALSE);

  Status = BdsLibBootViaBootOption (mHotkeyBootOption, mHotkeyBootOption->DevicePath, &ExitDataSize, &ExitData);

  if (EFI_ERROR (Status)) {
    //
    // Call platform action to indicate the boot fail
    //
    mHotkeyBootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));
    PlatformBdsBootFail (mHotkeyBootOption, Status, ExitData, ExitDataSize);
  } else {
    //
    // Call platform action to indicate the boot success
    //
    mHotkeyBootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));
    PlatformBdsBootSuccess (mHotkeyBootOption);
  }
  FreePool (mHotkeyBootOption->Description);
  FreePool (mHotkeyBootOption->DevicePath);
  FreePool (mHotkeyBootOption->LoadOptions);
  FreePool (mHotkeyBootOption);

  mHotkeyBootOption = NULL;

  return EFI_SUCCESS;
}

/**

  This is the common notification function for HotKeys, it will be registered
  with SimpleTextInEx protocol interface - RegisterKeyNotify() of ConIn handle.

  @param KeyData         A pointer to a buffer that is filled in with the keystroke
                         information for the key that was pressed.

  @retval  EFI_SUCCESS   KeyData is successfully processed.
  @return  EFI_NOT_FOUND Fail to find boot option variable.
**/
EFI_STATUS
EFIAPI
HotkeyCallback (
  IN EFI_KEY_DATA     *KeyData
)
{
  BOOLEAN            HotkeyCatched;
  LIST_ENTRY         BootLists;
  LIST_ENTRY         *Link;
  BDS_HOTKEY_OPTION  *Hotkey;
  UINT16             Buffer[10];
  EFI_STATUS         Status;
  EFI_KEY_DATA       *HotkeyData;

  if (mHotkeyBootOption != NULL) {
    //
    // Do not process sequential hotkey stroke until the current boot option returns
    //
    return EFI_SUCCESS;
  }

  Status                 = EFI_SUCCESS;

  for ( Link = GetFirstNode (&mHotkeyList)
      ; !IsNull (&mHotkeyList, Link)
      ; Link = GetNextNode (&mHotkeyList, Link)
      ) {
    HotkeyCatched = FALSE;
    Hotkey = BDS_HOTKEY_OPTION_FROM_LINK (Link);

    //
    // Is this Key Stroke we are waiting for?
    //
    ASSERT (Hotkey->WaitingKey < (sizeof (Hotkey->KeyData) / sizeof (Hotkey->KeyData[0])));
    HotkeyData = &Hotkey->KeyData[Hotkey->WaitingKey];
    if ((KeyData->Key.ScanCode == HotkeyData->Key.ScanCode) &&
        (KeyData->Key.UnicodeChar == HotkeyData->Key.UnicodeChar) &&
        (((KeyData->KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) ? 
          (KeyData->KeyState.KeyShiftState == HotkeyData->KeyState.KeyShiftState) : TRUE
        )
       ) {
      //
      // For hotkey of key combination, transit to next waiting state
      //
      Hotkey->WaitingKey++;

      if (Hotkey->WaitingKey == Hotkey->CodeCount) {
        //
        // Received the whole key stroke sequence
        //
        HotkeyCatched = TRUE;
      }
    } else {
      //
      // Receive an unexpected key stroke, reset to initial waiting state
      //
      Hotkey->WaitingKey = 0;
    }

    if (HotkeyCatched) {
      //
      // Reset to initial waiting state
      //
      Hotkey->WaitingKey = 0;

      //
      // Launch its BootOption
      //
      InitializeListHead (&BootLists);

      UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", Hotkey->BootOptionNumber);
      mHotkeyBootOption = BdsLibVariableToOption (&BootLists, Buffer);
    }
  }

  return Status;
}

/**
  Register the common HotKey notify function to given SimpleTextInEx protocol instance.

  @param SimpleTextInEx  Simple Text Input Ex protocol instance

  @retval  EFI_SUCCESS            Register hotkey notification function successfully.
  @retval  EFI_OUT_OF_RESOURCES   Unable to allocate necessary data structures.

**/
EFI_STATUS
HotkeyRegisterNotify (
  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *SimpleTextInEx
)
{
  UINTN              Index;
  EFI_STATUS         Status;
  LIST_ENTRY         *Link;
  BDS_HOTKEY_OPTION  *Hotkey;

  //
  // Register notification function for each hotkey
  //
  Link = GetFirstNode (&mHotkeyList);

  while (!IsNull (&mHotkeyList, Link)) {
    Hotkey = BDS_HOTKEY_OPTION_FROM_LINK (Link);

    Index = 0;
    do {
      Status = SimpleTextInEx->RegisterKeyNotify (
                                 SimpleTextInEx,
                                 &Hotkey->KeyData[Index],
                                 HotkeyCallback,
                                 &Hotkey->NotifyHandle
                                 );
      if (EFI_ERROR (Status)) {
        //
        // some of the hotkey registry failed
        //
        return Status;
      }
      Index ++;
    } while ((Index < Hotkey->CodeCount) && (Index < (sizeof (Hotkey->KeyData) / sizeof (EFI_KEY_DATA))));

    Link = GetNextNode (&mHotkeyList, Link);
  }

  return EFI_SUCCESS;
}

/**
  Callback function for SimpleTextInEx protocol install events

  @param Event           the event that is signaled.
  @param Context         not used here.

**/
VOID
EFIAPI
HotkeyEvent (
  IN EFI_EVENT    Event,
  IN VOID         *Context
  )
{
  EFI_STATUS                         Status;
  UINTN                              BufferSize;
  EFI_HANDLE                         Handle;
  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *SimpleTextInEx;

  while (TRUE) {
    BufferSize = sizeof (EFI_HANDLE);
    Status = gBS->LocateHandle (
                    ByRegisterNotify,
                    NULL,
                    mHotkeyRegistration,
                    &BufferSize,
                    &Handle
                    );
    if (EFI_ERROR (Status)) {
      //
      // If no more notification events exist
      //
      return ;
    }

    Status = gBS->HandleProtocol (
                    Handle,
                    &gEfiSimpleTextInputExProtocolGuid,
                    (VOID **) &SimpleTextInEx
                    );
    ASSERT_EFI_ERROR (Status);

    HotkeyRegisterNotify (SimpleTextInEx);
  }
}

/**
  Insert Key Option to hotkey list.

  @param KeyOption       The Hot Key Option to be added to hotkey list.

  @retval EFI_SUCCESS           Add to hotkey list success.
  @retval EFI_OUT_OF_RESOURCES  Fail to allocate memory resource.
**/
EFI_STATUS
HotkeyInsertList (
  IN EFI_KEY_OPTION     *KeyOption
)
{
  BDS_HOTKEY_OPTION  *HotkeyLeft;
  BDS_HOTKEY_OPTION  *HotkeyRight;
  UINTN              Index;
  EFI_BOOT_KEY_DATA  KeyOptions;
  UINT32             KeyShiftStateLeft;
  UINT32             KeyShiftStateRight;
  EFI_INPUT_KEY      *InputKey;
  EFI_KEY_DATA       *KeyData;

  HotkeyLeft = AllocateZeroPool (sizeof (BDS_HOTKEY_OPTION));
  if (HotkeyLeft == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  HotkeyLeft->Signature = BDS_HOTKEY_OPTION_SIGNATURE;
  HotkeyLeft->BootOptionNumber = KeyOption->BootOption;

  KeyOptions = KeyOption->KeyData;

  HotkeyLeft->CodeCount = (UINT8) KeyOptions.Options.InputKeyCount;

  //
  // Map key shift state from KeyOptions to EFI_KEY_DATA.KeyState
  //
  KeyShiftStateRight = EFI_SHIFT_STATE_VALID;
  if (KeyOptions.Options.ShiftPressed) {
    KeyShiftStateRight |= EFI_RIGHT_SHIFT_PRESSED;
  }
  if (KeyOptions.Options.ControlPressed) {
    KeyShiftStateRight |= EFI_RIGHT_CONTROL_PRESSED;
  }
  if (KeyOptions.Options.AltPressed) {
    KeyShiftStateRight |= EFI_RIGHT_ALT_PRESSED;
  }
  if (KeyOptions.Options.LogoPressed) {
    KeyShiftStateRight |= EFI_RIGHT_LOGO_PRESSED;
  }
  if (KeyOptions.Options.MenuPressed) {
    KeyShiftStateRight |= EFI_MENU_KEY_PRESSED;
  }
  if (KeyOptions.Options.SysReqPressed) {
    KeyShiftStateRight |= EFI_SYS_REQ_PRESSED;
  }

  KeyShiftStateLeft = (KeyShiftStateRight & 0xffffff00) | ((KeyShiftStateRight & 0xff) << 1);

  InputKey = (EFI_INPUT_KEY *) (((UINT8 *) KeyOption) + sizeof (EFI_KEY_OPTION));

  Index = 0;
  KeyData = &HotkeyLeft->KeyData[0];
  do {
    //
    // If Key CodeCount is 0, then only KeyData[0] is used;
    // if Key CodeCount is n, then KeyData[0]~KeyData[n-1] are used
    //
    KeyData->Key.ScanCode = InputKey[Index].ScanCode;
    KeyData->Key.UnicodeChar = InputKey[Index].UnicodeChar;
    KeyData->KeyState.KeyShiftState = KeyShiftStateLeft;

    Index++;
    KeyData++;
  } while (Index < HotkeyLeft->CodeCount);
  InsertTailList (&mHotkeyList, &HotkeyLeft->Link);

  if (KeyShiftStateLeft != KeyShiftStateRight) {
    //
    // Need an extra hotkey for shift key on right
    //
    HotkeyRight = AllocateCopyPool (sizeof (BDS_HOTKEY_OPTION), HotkeyLeft);
    if (HotkeyRight == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Index = 0;
    KeyData = &HotkeyRight->KeyData[0];
    do {
      //
      // Key.ScanCode and Key.UnicodeChar have already been initialized,
      // only need to update KeyState.KeyShiftState
      //
      KeyData->KeyState.KeyShiftState = KeyShiftStateRight;

      Index++;
      KeyData++;
    } while (Index < HotkeyRight->CodeCount);
    InsertTailList (&mHotkeyList, &HotkeyRight->Link);
  }

  return EFI_SUCCESS;
}

/**
  Return TRUE when the variable pointed by Name and Guid is a Key#### variable.

  @param Name         The name of the variable.
  @param Guid         The GUID of the variable.
  @param OptionNumber Return the option number parsed from the Name.

  @retval TRUE  The variable pointed by Name and Guid is a Key#### variable.
  @retval FALSE The variable pointed by Name and Guid isn't a Key#### variable.
**/
BOOLEAN
IsKeyOptionVariable (
  CHAR16        *Name,
  EFI_GUID      *Guid,
  UINT16        *OptionNumber
  )
{
  UINTN         Index;
  
  if (!CompareGuid (Guid, &gEfiGlobalVariableGuid) ||
      (StrSize (Name) != sizeof (L"Key####")) ||
      (StrnCmp (Name, L"Key", 3) != 0)
     ) {
    return FALSE;
  }

  *OptionNumber = 0;
  for (Index = 3; Index < 7; Index++) {
    if ((Name[Index] >= L'0') && (Name[Index] <= L'9')) {
      *OptionNumber = *OptionNumber * 16 + Name[Index] - L'0';
    } else if ((Name[Index] >= L'A') && (Name[Index] <= L'F')) {
      *OptionNumber = *OptionNumber * 16 + Name[Index] - L'A' + 10;
    } else {
      return FALSE;
    }
  }

  return TRUE;
}

/**
  Return an array of key option numbers.

  @param Count       Return the count of key option numbers.

  @return UINT16*    Pointer to an array of key option numbers;
**/
UINT16 *
EFIAPI
HotkeyGetOptionNumbers (
  OUT UINTN     *Count
  )
{
  EFI_STATUS                  Status;
  UINTN                       Index;
  CHAR16                      *Name;
  EFI_GUID                    Guid;
  UINTN                       NameSize;
  UINTN                       NewNameSize;
  UINT16                      *OptionNumbers;
  UINT16                      OptionNumber;

  if (Count == NULL) {
    return NULL;
  }

  *Count        = 0;
  OptionNumbers = NULL;

  NameSize = sizeof (CHAR16);
  Name     = AllocateZeroPool (NameSize);
  ASSERT (Name != NULL);
  while (TRUE) {
    NewNameSize = NameSize;
    Status = gRT->GetNextVariableName (&NewNameSize, Name, &Guid);
    if (Status == EFI_BUFFER_TOO_SMALL) {
      Name = ReallocatePool (NameSize, NewNameSize, Name);
      ASSERT (Name != NULL);
      Status = gRT->GetNextVariableName (&NewNameSize, Name, &Guid);
      NameSize = NewNameSize;
    }

    if (Status == EFI_NOT_FOUND) {
      break;
    }
    ASSERT_EFI_ERROR (Status);

    if (IsKeyOptionVariable (Name ,&Guid, &OptionNumber)) {
      OptionNumbers = ReallocatePool (
                        *Count * sizeof (UINT16),
                        (*Count + 1) * sizeof (UINT16),
                        OptionNumbers
                        );
      ASSERT (OptionNumbers != NULL);
      for (Index = 0; Index < *Count; Index++) {
        if (OptionNumber < OptionNumbers[Index]) {
          break;
        }
      }
      CopyMem (&OptionNumbers[Index + 1], &OptionNumbers[Index], (*Count - Index) * sizeof (UINT16));
      OptionNumbers[Index] = OptionNumber;
      (*Count)++;
    }
  }

  FreePool (Name);

  return OptionNumbers;
}

/**

  Process all the "Key####" variables, associate Hotkeys with corresponding Boot Options.

  @retval  EFI_SUCCESS    Hotkey services successfully initialized.
**/
EFI_STATUS
InitializeHotkeyService (
  VOID
  )
{
  EFI_STATUS      Status;
  UINT32          BootOptionSupport;
  UINT16          *KeyOptionNumbers;
  UINTN           KeyOptionCount;
  UINTN           Index;
  CHAR16          KeyOptionName[8];
  EFI_KEY_OPTION  *KeyOption;

  //
  // Export our capability - EFI_BOOT_OPTION_SUPPORT_KEY and EFI_BOOT_OPTION_SUPPORT_APP.
  // with maximum number of key presses of 3
  // Do not report the hotkey capability if PcdConInConnectOnDemand is enabled.
  //
  BootOptionSupport = EFI_BOOT_OPTION_SUPPORT_APP;
  if (!PcdGetBool (PcdConInConnectOnDemand)) {
    BootOptionSupport |= EFI_BOOT_OPTION_SUPPORT_KEY;
    SET_BOOT_OPTION_SUPPORT_KEY_COUNT (BootOptionSupport, 3);
  }

  Status = gRT->SetVariable (
                  L"BootOptionSupport",
                  &gEfiGlobalVariableGuid,
                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                  sizeof (UINT32),
                  &BootOptionSupport
                  );
  //
  // Platform needs to make sure setting volatile variable before calling 3rd party code shouldn't fail.
  //
  ASSERT_EFI_ERROR (Status);

  KeyOptionNumbers = HotkeyGetOptionNumbers (&KeyOptionCount);
  for (Index = 0; Index < KeyOptionCount; Index ++) {
    UnicodeSPrint (KeyOptionName, sizeof (KeyOptionName), L"Key%04x", KeyOptionNumbers[Index]);
    GetEfiGlobalVariable2 (KeyOptionName, (VOID **) &KeyOption, NULL);
    ASSERT (KeyOption != NULL);
    if (IsKeyOptionValid (KeyOption)) {
      HotkeyInsertList (KeyOption);
    }
    FreePool (KeyOption);
  }

  if (KeyOptionNumbers != NULL) {
    FreePool (KeyOptionNumbers);
  }

  //
  // Register Protocol notify for Hotkey service
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  HotkeyEvent,
                  NULL,
                  &mHotkeyEvent
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Register for protocol notifications on this event
  //
  Status = gBS->RegisterProtocolNotify (
                  &gEfiSimpleTextInputExProtocolGuid,
                  mHotkeyEvent,
                  &mHotkeyRegistration
                  );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

