/** @file
  Main file for SetVar shell Debug1 function.

  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2010 - 2018, 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 "UefiShellDebug1CommandsLib.h"

STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
  {L"-guid", TypeValue},
  {L"-bs", TypeFlag},
  {L"-rt", TypeFlag},
  {L"-nv", TypeFlag},
  {NULL, TypeMax}
  };

typedef enum {
  DataTypeHexNumber   = 0,
  DataTypeHexArray    = 1,
  DataTypeAscii       = 2,
  DataTypeUnicode     = 3,
  DataTypeDevicePath  = 4,
  DataTypeUnKnow      = 5
} DATA_TYPE;

typedef union {
  UINT8     HexNumber8;
  UINT16    HexNumber16;
  UINT32    HexNumber32;
  UINT64    HexNumber64;
} HEX_NUMBER;

/**
  Check if the input is a (potentially empty) string of hexadecimal nibbles.

  @param[in] String  The CHAR16 string to check.

  @retval FALSE  A character has been found in String for which
                 ShellIsHexaDecimalDigitCharacter() returned FALSE.

  @retval TRUE   Otherwise. (Note that this covers the case when String is
                 empty.)
**/
BOOLEAN
IsStringOfHexNibbles (
  IN CONST CHAR16  *String
  )
{
  CONST CHAR16 *Pos;

  for (Pos = String; *Pos != L'\0'; ++Pos) {
    if (!ShellIsHexaDecimalDigitCharacter (*Pos)) {
      return FALSE;
    }
  }
  return TRUE;
}

/**
  Function to check the TYPE of Data.

  @param[in]    Data          The Data to be check.

  @retval       DATA_TYPE     The TYPE of Data.
**/
DATA_TYPE
TestDataType (
  IN CONST CHAR16  *Data
  )
{
  if (Data[0] == L'0' && (Data[1] == L'x' || Data[1] == L'X')) {
    if (IsStringOfHexNibbles (Data+2) && StrLen (Data + 2) <= 16) {
      return DataTypeHexNumber;
    } else {
      return DataTypeUnKnow;
    }
  } else if (Data[0] == L'H') {
    if (IsStringOfHexNibbles (Data + 1) && StrLen (Data + 1) % 2 == 0) {
      return DataTypeHexArray;
    } else {
      return DataTypeUnKnow;
    }
  } else if (Data[0] == L'S') {
    return DataTypeAscii;
  } else if (Data[0] == L'L') {
    return DataTypeUnicode;
  } else if (Data[0] == L'P' || StrnCmp (Data, L"--", 2) == 0) {
    return DataTypeDevicePath;
  }

  if (IsStringOfHexNibbles (Data) && StrLen (Data) % 2 == 0) {
    return DataTypeHexArray;
  }

  return DataTypeAscii;
}

/**
  Function to parse the Data by the type of Data, and save in the Buffer.

  @param[in]      Data                A pointer to a buffer to be parsed.
  @param[out]     Buffer              A pointer to a buffer to hold the return data.
  @param[in,out]  BufferSize          On input, indicates the size of Buffer in bytes.
                                      On output,indicates the size of data return in Buffer.
                                      Or the size in bytes of the buffer needed to obtain.

  @retval   EFI_INVALID_PARAMETER     The Buffer or BufferSize is NULL.
  @retval   EFI_BUFFER_TOO_SMALL      The Buffer is too small to hold the data.
  @retval   EFI_OUT_OF_RESOURCES      A memory allcation failed.
  @retval   EFI_SUCCESS               The Data parsed successful and save in the Buffer.
**/
EFI_STATUS
ParseParameterData (
  IN CONST CHAR16   *Data,
  OUT VOID          *Buffer,
  IN OUT UINTN      *BufferSize
  )
{
  UINT64                    HexNumber;
  UINTN                     HexNumberLen;
  UINTN                     Size;
  CHAR8                     *AsciiBuffer;
  DATA_TYPE                 DataType;
  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
  EFI_STATUS                Status;

  HexNumber                 = 0;
  HexNumberLen              = 0;
  Size                      = 0;
  AsciiBuffer               = NULL;
  DevPath                   = NULL;
  Status                    = EFI_SUCCESS;

  if (Data == NULL || BufferSize == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  DataType = TestDataType (Data);
  if (DataType == DataTypeHexNumber) {
    //
    // hex number
    //
    StrHexToUint64S (Data + 2, NULL, &HexNumber);
    HexNumberLen = StrLen (Data + 2);
    if (HexNumberLen >= 1 && HexNumberLen <= 2) {
      Size = 1;
    } else if (HexNumberLen >= 3 && HexNumberLen <= 4) {
      Size = 2;
    } else if (HexNumberLen >= 5 && HexNumberLen <= 8) {
      Size = 4;
    } else if (HexNumberLen >= 9 && HexNumberLen <= 16) {
      Size = 8;
    }
    if (Buffer != NULL && *BufferSize >= Size) {
      CopyMem(Buffer, (VOID *)&HexNumber, Size);
    } else {
      Status = EFI_BUFFER_TOO_SMALL;
    }
    *BufferSize = Size;
  } else if (DataType == DataTypeHexArray) {
    //
    // hex array
    //
    if (*Data == L'H') {
      Data = Data + 1;
    }

    Size = StrLen (Data) / 2;
    if (Buffer != NULL && *BufferSize >= Size) {
      StrHexToBytes(Data, StrLen  (Data), (UINT8 *)Buffer, Size);
    } else {
      Status = EFI_BUFFER_TOO_SMALL;
    }
    *BufferSize = Size;
  } else if (DataType == DataTypeAscii) {
    //
    // ascii text
    //
    if (*Data == L'S') {
      Data = Data + 1;
    }
    AsciiBuffer = AllocateZeroPool (StrSize (Data) / 2);
    if (AsciiBuffer == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
    } else {
      AsciiSPrint (AsciiBuffer, StrSize (Data) / 2, "%s", (CHAR8 *)Data);

      Size = StrSize (Data) / 2 - 1;
      if (Buffer != NULL && *BufferSize >= Size) {
        CopyMem (Buffer, AsciiBuffer, Size);
      } else {
        Status = EFI_BUFFER_TOO_SMALL;
      }
      *BufferSize = Size;
    }
    SHELL_FREE_NON_NULL (AsciiBuffer);
  } else if (DataType == DataTypeUnicode) {
    //
    // unicode text
    //
    if (*Data == L'L') {
      Data = Data + 1;
    }
    Size = StrSize (Data) - sizeof (CHAR16);
    if (Buffer != NULL && *BufferSize >= Size) {
      CopyMem (Buffer, Data, Size);
    } else {
      Status = EFI_BUFFER_TOO_SMALL;
    }
    *BufferSize = Size;
  } else if (DataType == DataTypeDevicePath) {
    if (*Data == L'P') {
      Data = Data + 1;
    } else if (StrnCmp (Data, L"--", 2) == 0) {
      Data = Data + 2;
    }
    DevPath = ConvertTextToDevicePath (Data);
    if (DevPath == NULL) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, L"setvar");
      Status = EFI_INVALID_PARAMETER;
    } else {
      Size = GetDevicePathSize (DevPath);
      if (Buffer != NULL && *BufferSize >= Size) {
        CopyMem (Buffer, DevPath, Size);
      } else {
        Status = EFI_BUFFER_TOO_SMALL;
      }
      *BufferSize = Size;
    }
    SHELL_FREE_NON_NULL (DevPath);
  } else {
    Status = EFI_INVALID_PARAMETER;
  }

  return Status;
}

/**
  Function to get each data from parameters.

  @param[in]    Package               The package of checked values.
  @param[out]   Buffer                A pointer to a buffer to hold the return data.
  @param[out]   BufferSize            Indicates the size of data in bytes return in Buffer.

  @retval   EFI_INVALID_PARAMETER     Buffer or BufferSize is NULL.
  @retval   EFI_OUT_OF_RESOURCES      A memory allcation failed.
  @retval   EFI_SUCCESS               Get each parameter data was successful.
**/
EFI_STATUS
GetVariableDataFromParameter (
  IN CONST LIST_ENTRY *Package,
  OUT UINT8           **Buffer,
  OUT UINTN           *BufferSize
  )
{
  CONST CHAR16    *TempData;
  UINTN           Index;
  UINTN           TotalSize;
  UINTN           Size;
  UINT8           *BufferWalker;
  EFI_STATUS      Status;

  TotalSize       = 0;
  Size            = 0;
  Status          = EFI_SUCCESS;

  if (BufferSize == NULL || Buffer == NULL || ShellCommandLineGetCount (Package) < 3) {
    return EFI_INVALID_PARAMETER;
  }

  for (Index = 2; Index < ShellCommandLineGetCount (Package); Index++) {
    TempData = ShellCommandLineGetRawValue (Package, Index);
    ASSERT (TempData != NULL);

    if (TempData[0] != L'=') {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", TempData);
      return EFI_INVALID_PARAMETER;
    }

    TempData = TempData + 1;
    Size = 0;
    Status = ParseParameterData (TempData, NULL, &Size);
    if (EFI_ERROR (Status)) {
      if (Status == EFI_BUFFER_TOO_SMALL) {
        //
        // We expect return EFI_BUFFER_TOO_SMALL when pass 'NULL' as second parameter to the function ParseParameterData.
        //
        TotalSize += Size;
      } else {
        if (Status == EFI_INVALID_PARAMETER) {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", TempData);
        } else if (Status == EFI_NOT_FOUND) {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, L"setvar");
        }
        return Status;
      }
    }
  }

  *BufferSize = TotalSize;
  *Buffer = AllocateZeroPool (TotalSize);

  if (*Buffer == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
  } else {
    BufferWalker = *Buffer;
    for (Index = 2; Index < ShellCommandLineGetCount (Package); Index++) {
      TempData = ShellCommandLineGetRawValue (Package, Index);
      TempData = TempData + 1;

      Size = TotalSize;
      Status = ParseParameterData (TempData, (VOID *)BufferWalker, &Size);
      if (!EFI_ERROR (Status)) {
        BufferWalker = BufferWalker + Size;
        TotalSize = TotalSize - Size;
      } else {
        return Status;
      }
    }
  }

  return EFI_SUCCESS;
}

/**
  Function for 'setvar' command.

  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
**/
SHELL_STATUS
EFIAPI
ShellCommandRunSetVar (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS          Status;
  RETURN_STATUS       RStatus;
  LIST_ENTRY          *Package;
  CHAR16              *ProblemParam;
  SHELL_STATUS        ShellStatus;
  CONST CHAR16        *VariableName;
  EFI_GUID            Guid;
  CONST CHAR16        *StringGuid;
  UINT32              Attributes;
  VOID                *Buffer;
  UINTN               Size;
  UINTN               LoopVar;

  ShellStatus         = SHELL_SUCCESS;
  Status              = EFI_SUCCESS;
  Buffer              = NULL;
  Size                = 0;
  Attributes          = 0;

  //
  // initialize the shell lib (we must be in non-auto-init...)
  //
  Status = ShellInitialize();
  ASSERT_EFI_ERROR(Status);

  Status = CommandInit();
  ASSERT_EFI_ERROR(Status);

  //
  // parse the command line
  //
  Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
  if (EFI_ERROR(Status)) {
    if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"setvar", ProblemParam);
      FreePool(ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT(FALSE);
    }
  } else if (ShellCommandLineCheckDuplicate (Package,&ProblemParam) != EFI_SUCCESS) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DUPLICATE), gShellDebug1HiiHandle, L"setvar", ProblemParam);
      FreePool(ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
  } else {
    if (ShellCommandLineGetCount(Package) < 2) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"setvar");
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      VariableName  = ShellCommandLineGetRawValue(Package, 1);
      if (!ShellCommandLineGetFlag(Package, L"-guid")){
        CopyGuid(&Guid, &gEfiGlobalVariableGuid);
      } else {
        StringGuid = ShellCommandLineGetValue(Package, L"-guid");
        RStatus = StrToGuid (StringGuid, &Guid);
        if (RETURN_ERROR (RStatus) || (StringGuid[GUID_STRING_LENGTH] != L'\0')) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", StringGuid);
          ShellStatus = SHELL_INVALID_PARAMETER;
        }
      }

      if (ShellCommandLineGetCount(Package) == 2) {
        //
        // Display
        //
        Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
        if (Status == EFI_BUFFER_TOO_SMALL) {
          Buffer = AllocateZeroPool(Size);
          Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
        }
        if (!EFI_ERROR(Status) && Buffer != NULL) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_SETVAR_PRINT), gShellDebug1HiiHandle, &Guid, VariableName, Size);
          for (LoopVar = 0; LoopVar < Size; LoopVar++) {
            ShellPrintEx(-1, -1, L"%02x ", ((UINT8*)Buffer)[LoopVar]);
          }
          ShellPrintEx(-1, -1, L"\r\n");
        } else {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_GET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);
          ShellStatus = SHELL_ACCESS_DENIED;
        }
      } else {
        //
        // Create, Delete or Modify.
        //
        Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
        if (Status == EFI_BUFFER_TOO_SMALL) {
          Buffer = AllocateZeroPool(Size);
          Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
        }
        if (EFI_ERROR(Status) || Buffer == NULL) {
          //
          // Creating a new variable.  determine attributes from command line.
          //
          Attributes = 0;
          if (ShellCommandLineGetFlag(Package, L"-bs")) {
            Attributes |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
          }
          if (ShellCommandLineGetFlag(Package, L"-rt")) {
            Attributes |= EFI_VARIABLE_RUNTIME_ACCESS |
                          EFI_VARIABLE_BOOTSERVICE_ACCESS;
          }
          if (ShellCommandLineGetFlag(Package, L"-nv")) {
            Attributes |= EFI_VARIABLE_NON_VOLATILE;
          }
        }
        SHELL_FREE_NON_NULL(Buffer);

        Size = 0;
        Status = GetVariableDataFromParameter(Package, (UINT8 **)&Buffer, &Size);
        if (!EFI_ERROR(Status)) {
          Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, Size, Buffer);
        }
        if (EFI_ERROR(Status)) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, L"setvar", &Guid, VariableName);
          ShellStatus = SHELL_ACCESS_DENIED;
        } else {
          ASSERT(ShellStatus == SHELL_SUCCESS);
        }
      }
    }
    ShellCommandLineFreeVarList (Package);
  }

  if (Buffer != NULL) {
    FreePool(Buffer);
  }

  return (ShellStatus);
}
