/** @file
  function declarations for shell environment functions.

  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Shell.h"

#define INIT_NAME_BUFFER_SIZE  128
#define INIT_DATA_BUFFER_SIZE  1024

//
// The list is used to cache the environment variables.
//
ENV_VAR_LIST  gShellEnvVarList;

/**
  Reports whether an environment variable is Volatile or Non-Volatile.

  @param EnvVarName             The name of the environment variable in question
  @param Volatile               Return TRUE if the environment variable is volatile

  @retval EFI_SUCCESS           The volatile attribute is returned successfully
  @retval others                Some errors happened.
**/
EFI_STATUS
IsVolatileEnv (
  IN CONST CHAR16  *EnvVarName,
  OUT BOOLEAN      *Volatile
  )
{
  EFI_STATUS  Status;
  UINTN       Size;
  VOID        *Buffer;
  UINT32      Attribs;

  ASSERT (Volatile != NULL);

  Size   = 0;
  Buffer = NULL;

  //
  // get the variable
  //
  Status = gRT->GetVariable (
                  (CHAR16 *)EnvVarName,
                  &gShellVariableGuid,
                  &Attribs,
                  &Size,
                  Buffer
                  );
  if (Status == EFI_BUFFER_TOO_SMALL) {
    Buffer = AllocateZeroPool (Size);
    if (Buffer == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Status = gRT->GetVariable (
                    (CHAR16 *)EnvVarName,
                    &gShellVariableGuid,
                    &Attribs,
                    &Size,
                    Buffer
                    );
    FreePool (Buffer);
  }

  //
  // not found means volatile
  //
  if (Status == EFI_NOT_FOUND) {
    *Volatile = TRUE;
    return EFI_SUCCESS;
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // check for the Non Volatile bit
  //
  *Volatile = !(BOOLEAN)((Attribs & EFI_VARIABLE_NON_VOLATILE) == EFI_VARIABLE_NON_VOLATILE);
  return EFI_SUCCESS;
}

/**
  free function for ENV_VAR_LIST objects.

  @param[in] List               The pointer to pointer to list.
**/
VOID
FreeEnvironmentVariableList (
  IN LIST_ENTRY  *List
  )
{
  ENV_VAR_LIST  *Node;

  ASSERT (List != NULL);
  if (List == NULL) {
    return;
  }

  for ( Node = (ENV_VAR_LIST *)GetFirstNode (List)
        ; !IsListEmpty (List)
        ; Node = (ENV_VAR_LIST *)GetFirstNode (List)
        )
  {
    ASSERT (Node != NULL);
    RemoveEntryList (&Node->Link);
    if (Node->Key != NULL) {
      FreePool (Node->Key);
    }

    if (Node->Val != NULL) {
      FreePool (Node->Val);
    }

    FreePool (Node);
  }
}

/**
  Creates a list of all Shell-Guid-based environment variables.

  @param[in, out] ListHead       The pointer to pointer to LIST ENTRY object for
                                 storing this list.

  @retval EFI_SUCCESS           the list was created successfully.
**/
EFI_STATUS
GetEnvironmentVariableList (
  IN OUT LIST_ENTRY  *ListHead
  )
{
  CHAR16        *VariableName;
  UINTN         NameSize;
  UINTN         NameBufferSize;
  EFI_STATUS    Status;
  EFI_GUID      Guid;
  UINTN         ValSize;
  UINTN         ValBufferSize;
  ENV_VAR_LIST  *VarList;

  if (ListHead == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  Status = EFI_SUCCESS;

  ValBufferSize  = INIT_DATA_BUFFER_SIZE;
  NameBufferSize = INIT_NAME_BUFFER_SIZE;
  VariableName   = AllocateZeroPool (NameBufferSize);
  if (VariableName == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  *VariableName = CHAR_NULL;

  while (!EFI_ERROR (Status)) {
    NameSize = NameBufferSize;
    Status   = gRT->GetNextVariableName (&NameSize, VariableName, &Guid);
    if (Status == EFI_NOT_FOUND) {
      Status = EFI_SUCCESS;
      break;
    } else if (Status == EFI_BUFFER_TOO_SMALL) {
      NameBufferSize = NameSize > NameBufferSize * 2 ? NameSize : NameBufferSize * 2;
      SHELL_FREE_NON_NULL (VariableName);
      VariableName = AllocateZeroPool (NameBufferSize);
      if (VariableName == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        break;
      }

      NameSize = NameBufferSize;
      Status   = gRT->GetNextVariableName (&NameSize, VariableName, &Guid);
    }

    if (!EFI_ERROR (Status) && CompareGuid (&Guid, &gShellVariableGuid)) {
      VarList = AllocateZeroPool (sizeof (ENV_VAR_LIST));
      if (VarList == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
      } else {
        ValSize = ValBufferSize;
        //
        // We need another CHAR16 to save '\0' in VarList->Val.
        //
        VarList->Val = AllocateZeroPool (ValSize + sizeof (CHAR16));
        if (VarList->Val == NULL) {
          SHELL_FREE_NON_NULL (VarList);
          Status = EFI_OUT_OF_RESOURCES;
          break;
        }

        Status = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES (VariableName, &VarList->Atts, &ValSize, VarList->Val);
        if (Status == EFI_BUFFER_TOO_SMALL) {
          ValBufferSize = ValSize > ValBufferSize * 2 ? ValSize : ValBufferSize * 2;
          SHELL_FREE_NON_NULL (VarList->Val);
          //
          // We need another CHAR16 to save '\0' in VarList->Val.
          //
          VarList->Val = AllocateZeroPool (ValBufferSize + sizeof (CHAR16));
          if (VarList->Val == NULL) {
            SHELL_FREE_NON_NULL (VarList);
            Status = EFI_OUT_OF_RESOURCES;
            break;
          }

          ValSize = ValBufferSize;
          Status  = SHELL_GET_ENVIRONMENT_VARIABLE_AND_ATTRIBUTES (VariableName, &VarList->Atts, &ValSize, VarList->Val);
        }

        if (!EFI_ERROR (Status)) {
          VarList->Key = AllocateCopyPool (StrSize (VariableName), VariableName);
          if (VarList->Key == NULL) {
            SHELL_FREE_NON_NULL (VarList->Val);
            SHELL_FREE_NON_NULL (VarList);
            Status = EFI_OUT_OF_RESOURCES;
          } else {
            InsertTailList (ListHead, &VarList->Link);
          }
        } else {
          SHELL_FREE_NON_NULL (VarList->Val);
          SHELL_FREE_NON_NULL (VarList);
        }
      } // if (VarList == NULL) ... else ...
    } // compare guid
  } // while

  SHELL_FREE_NON_NULL (VariableName);

  if (EFI_ERROR (Status)) {
    FreeEnvironmentVariableList (ListHead);
  }

  return (Status);
}

/**
  Sets a list of all Shell-Guid-based environment variables.  this will
  also eliminate all existing shell environment variables (even if they
  are not on the list).

  This function will also deallocate the memory from List.

  @param[in] ListHead           The pointer to LIST_ENTRY from
                                GetShellEnvVarList().

  @retval EFI_SUCCESS           the list was Set successfully.
**/
EFI_STATUS
SetEnvironmentVariableList (
  IN LIST_ENTRY  *ListHead
  )
{
  ENV_VAR_LIST  VarList;
  ENV_VAR_LIST  *Node;
  EFI_STATUS    Status;
  UINTN         Size;

  InitializeListHead (&VarList.Link);

  //
  // Delete all the current environment variables
  //
  Status = GetEnvironmentVariableList (&VarList.Link);
  ASSERT_EFI_ERROR (Status);

  for ( Node = (ENV_VAR_LIST *)GetFirstNode (&VarList.Link)
        ; !IsNull (&VarList.Link, &Node->Link)
        ; Node = (ENV_VAR_LIST *)GetNextNode (&VarList.Link, &Node->Link)
        )
  {
    if (Node->Key != NULL) {
      Status = SHELL_DELETE_ENVIRONMENT_VARIABLE (Node->Key);
    }

    ASSERT_EFI_ERROR (Status);
  }

  FreeEnvironmentVariableList (&VarList.Link);

  //
  // set all the variables from the list
  //
  for ( Node = (ENV_VAR_LIST *)GetFirstNode (ListHead)
        ; !IsNull (ListHead, &Node->Link)
        ; Node = (ENV_VAR_LIST *)GetNextNode (ListHead, &Node->Link)
        )
  {
    Size = StrSize (Node->Val) - sizeof (CHAR16);
    if (Node->Atts & EFI_VARIABLE_NON_VOLATILE) {
      Status = SHELL_SET_ENVIRONMENT_VARIABLE_NV (Node->Key, Size, Node->Val);
    } else {
      Status = SHELL_SET_ENVIRONMENT_VARIABLE_V (Node->Key, Size, Node->Val);
    }

    ASSERT_EFI_ERROR (Status);
  }

  FreeEnvironmentVariableList (ListHead);

  return (Status);
}

/**
  sets a list of all Shell-Guid-based environment variables.

  @param Environment        Points to a NULL-terminated array of environment
                            variables with the format 'x=y', where x is the
                            environment variable name and y is the value.

  @retval EFI_SUCCESS       The command executed successfully.
  @retval EFI_INVALID_PARAMETER The parameter is invalid.
  @retval EFI_OUT_OF_RESOURCES Out of resources.

  @sa SetEnvironmentVariableList
**/
EFI_STATUS
SetEnvironmentVariables (
  IN CONST CHAR16  **Environment
  )
{
  CONST CHAR16  *CurrentString;
  UINTN         CurrentCount;
  ENV_VAR_LIST  *VarList;
  ENV_VAR_LIST  *Node;

  VarList = NULL;

  if (Environment == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // Build a list identical to the ones used for get/set list functions above
  //
  for ( CurrentCount = 0
        ;
        ; CurrentCount++
        )
  {
    CurrentString = Environment[CurrentCount];
    if (CurrentString == NULL) {
      break;
    }

    ASSERT (StrStr (CurrentString, L"=") != NULL);
    Node = AllocateZeroPool (sizeof (ENV_VAR_LIST));
    if (Node == NULL) {
      SetEnvironmentVariableList (&VarList->Link);
      return (EFI_OUT_OF_RESOURCES);
    }

    Node->Key = AllocateZeroPool ((StrStr (CurrentString, L"=") - CurrentString + 1) * sizeof (CHAR16));
    if (Node->Key == NULL) {
      SHELL_FREE_NON_NULL (Node);
      SetEnvironmentVariableList (&VarList->Link);
      return (EFI_OUT_OF_RESOURCES);
    }

    //
    // Copy the string into the Key, leaving the last character allocated as NULL to terminate
    //
    StrnCpyS (
      Node->Key,
      StrStr (CurrentString, L"=") - CurrentString + 1,
      CurrentString,
      StrStr (CurrentString, L"=") - CurrentString
      );

    //
    // ValueSize = TotalSize - already removed size - size for '=' + size for terminator (the last 2 items cancel each other)
    //
    Node->Val = AllocateCopyPool (StrSize (CurrentString) - StrSize (Node->Key), CurrentString + StrLen (Node->Key) + 1);
    if (Node->Val == NULL) {
      SHELL_FREE_NON_NULL (Node->Key);
      SHELL_FREE_NON_NULL (Node);
      SetEnvironmentVariableList (&VarList->Link);
      return (EFI_OUT_OF_RESOURCES);
    }

    Node->Atts = EFI_VARIABLE_BOOTSERVICE_ACCESS;

    if (VarList == NULL) {
      VarList = AllocateZeroPool (sizeof (ENV_VAR_LIST));
      if (VarList == NULL) {
        SHELL_FREE_NON_NULL (Node->Key);
        SHELL_FREE_NON_NULL (Node->Val);
        SHELL_FREE_NON_NULL (Node);
        return (EFI_OUT_OF_RESOURCES);
      }

      InitializeListHead (&VarList->Link);
    }

    InsertTailList (&VarList->Link, &Node->Link);
  } // for loop

  //
  // set this new list as the set of all environment variables.
  // this function also frees the memory and deletes all pre-existing
  // shell-guid based environment variables.
  //
  return (SetEnvironmentVariableList (&VarList->Link));
}

/**
  Find an environment variable in the gShellEnvVarList.

  @param Key        The name of the environment variable.
  @param Value      The value of the environment variable, the buffer
                    shoule be freed by the caller.
  @param ValueSize  The size in bytes of the environment variable
                    including the tailing CHAR_NELL.
  @param Atts       The attributes of the variable.

  @retval EFI_SUCCESS       The command executed successfully.
  @retval EFI_NOT_FOUND     The environment variable is not found in
                            gShellEnvVarList.

**/
EFI_STATUS
ShellFindEnvVarInList (
  IN  CONST CHAR16  *Key,
  OUT CHAR16        **Value,
  OUT UINTN         *ValueSize,
  OUT UINT32        *Atts OPTIONAL
  )
{
  ENV_VAR_LIST  *Node;

  if ((Key == NULL) || (Value == NULL) || (ValueSize == NULL)) {
    return SHELL_INVALID_PARAMETER;
  }

  for ( Node = (ENV_VAR_LIST *)GetFirstNode (&gShellEnvVarList.Link)
        ; !IsNull (&gShellEnvVarList.Link, &Node->Link)
        ; Node = (ENV_VAR_LIST *)GetNextNode (&gShellEnvVarList.Link, &Node->Link)
        )
  {
    if ((Node->Key != NULL) && (StrCmp (Key, Node->Key) == 0)) {
      *Value     = AllocateCopyPool (StrSize (Node->Val), Node->Val);
      *ValueSize = StrSize (Node->Val);
      if (Atts != NULL) {
        *Atts = Node->Atts;
      }

      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}

/**
  Add an environment variable into gShellEnvVarList.

  @param Key        The name of the environment variable.
  @param Value      The value of environment variable.
  @param ValueSize  The size in bytes of the environment variable
                    including the tailing CHAR_NULL
  @param Atts       The attributes of the variable.

  @retval EFI_SUCCESS  The environment variable was added to list successfully.
  @retval others       Some errors happened.

**/
EFI_STATUS
ShellAddEnvVarToList (
  IN CONST CHAR16  *Key,
  IN CONST CHAR16  *Value,
  IN UINTN         ValueSize,
  IN UINT32        Atts
  )
{
  ENV_VAR_LIST  *Node;
  CHAR16        *LocalKey;
  CHAR16        *LocalValue;

  if ((Key == NULL) || (Value == NULL) || (ValueSize == 0)) {
    return EFI_INVALID_PARAMETER;
  }

  LocalValue = AllocateCopyPool (ValueSize, Value);
  if (LocalValue == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Update the variable value if it exists in gShellEnvVarList.
  //
  for ( Node = (ENV_VAR_LIST *)GetFirstNode (&gShellEnvVarList.Link)
        ; !IsNull (&gShellEnvVarList.Link, &Node->Link)
        ; Node = (ENV_VAR_LIST *)GetNextNode (&gShellEnvVarList.Link, &Node->Link)
        )
  {
    if ((Node->Key != NULL) && (StrCmp (Key, Node->Key) == 0)) {
      Node->Atts = Atts;
      SHELL_FREE_NON_NULL (Node->Val);
      Node->Val = LocalValue;
      return EFI_SUCCESS;
    }
  }

  //
  // If the environment variable key doesn't exist in list just insert
  // a new node.
  //
  LocalKey = AllocateCopyPool (StrSize (Key), Key);
  if (LocalKey == NULL) {
    FreePool (LocalValue);
    return EFI_OUT_OF_RESOURCES;
  }

  Node = (ENV_VAR_LIST *)AllocateZeroPool (sizeof (ENV_VAR_LIST));
  if (Node == NULL) {
    FreePool (LocalKey);
    FreePool (LocalValue);
    return EFI_OUT_OF_RESOURCES;
  }

  Node->Key  = LocalKey;
  Node->Val  = LocalValue;
  Node->Atts = Atts;
  InsertTailList (&gShellEnvVarList.Link, &Node->Link);

  return EFI_SUCCESS;
}

/**
  Remove a specified environment variable in gShellEnvVarList.

  @param Key        The name of the environment variable.

  @retval EFI_SUCCESS       The command executed successfully.
  @retval EFI_NOT_FOUND     The environment variable is not found in
                            gShellEnvVarList.
**/
EFI_STATUS
ShellRemvoeEnvVarFromList (
  IN CONST CHAR16  *Key
  )
{
  ENV_VAR_LIST  *Node;

  if (Key == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  for ( Node = (ENV_VAR_LIST *)GetFirstNode (&gShellEnvVarList.Link)
        ; !IsNull (&gShellEnvVarList.Link, &Node->Link)
        ; Node = (ENV_VAR_LIST *)GetNextNode (&gShellEnvVarList.Link, &Node->Link)
        )
  {
    if ((Node->Key != NULL) && (StrCmp (Key, Node->Key) == 0)) {
      SHELL_FREE_NON_NULL (Node->Key);
      SHELL_FREE_NON_NULL (Node->Val);
      RemoveEntryList (&Node->Link);
      SHELL_FREE_NON_NULL (Node);
      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}

/**
  Initialize the gShellEnvVarList and cache all Shell-Guid-based environment
  variables.

**/
EFI_STATUS
ShellInitEnvVarList (
  VOID
  )
{
  EFI_STATUS  Status;

  InitializeListHead (&gShellEnvVarList.Link);
  Status = GetEnvironmentVariableList (&gShellEnvVarList.Link);

  return Status;
}

/**
  Destructe the gShellEnvVarList.

**/
VOID
ShellFreeEnvVarList (
  VOID
  )
{
  FreeEnvironmentVariableList (&gShellEnvVarList.Link);
  InitializeListHead (&gShellEnvVarList.Link);

  return;
}
