/** @file
  HII Library implementation that uses DXE protocols and services.

  Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>
 (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "InternalHiiLib.h"

/**
  This function create a new string in String Package or updates an existing
  string in a String Package.  If StringId is 0, then a new string is added to
  a String Package.  If StringId is not zero, then a string in String Package is
  updated.  If SupportedLanguages is NULL, then the string is added or updated
  for all the languages that the String Package supports.  If SupportedLanguages
  is not NULL, then the string is added or updated for the set of languages
  specified by SupportedLanguages.

  If HiiHandle is NULL, then ASSERT().
  If String is NULL, then ASSERT().

  @param[in]  HiiHandle           A handle that was previously registered in the
                                  HII Database.
  @param[in]  StringId            If zero, then a new string is created in the
                                  String Package associated with HiiHandle.  If
                                  non-zero, then the string specified by StringId
                                  is updated in the String Package  associated
                                  with HiiHandle.
  @param[in]  String              A pointer to the Null-terminated Unicode string
                                  to add or update in the String Package associated
                                  with HiiHandle.
  @param[in]  SupportedLanguages  A pointer to a Null-terminated ASCII string of
                                  language codes.  If this parameter is NULL, then
                                  String is added or updated in the String Package
                                  associated with HiiHandle for all the languages
                                  that the String Package supports.  If this
                                  parameter is not NULL, then then String is added
                                  or updated in the String Package associated with
                                  HiiHandle for the set oflanguages specified by
                                  SupportedLanguages.  The format of
                                  SupportedLanguages must follow the language
                                  format assumed the HII Database.

  @retval 0      The string could not be added or updated in the String Package.
  @retval Other  The EFI_STRING_ID of the newly added or updated string.

**/
EFI_STRING_ID
EFIAPI
HiiSetString (
  IN EFI_HII_HANDLE    HiiHandle,
  IN EFI_STRING_ID     StringId             OPTIONAL,
  IN CONST EFI_STRING  String,
  IN CONST CHAR8       *SupportedLanguages  OPTIONAL
  )
{
  EFI_STATUS  Status;
  CHAR8       *AllocatedLanguages;
  CHAR8       *Supported;
  CHAR8       *Language;

  ASSERT (HiiHandle != NULL);
  ASSERT (String != NULL);

  if (SupportedLanguages == NULL) {
    //
    // Retrieve the languages that the package specified by HiiHandle supports
    //
    AllocatedLanguages = HiiGetSupportedLanguages (HiiHandle);
  } else {
    //
    // Allocate a copy of the SupportLanguages string that passed in
    //
    AllocatedLanguages = AllocateCopyPool (AsciiStrSize (SupportedLanguages), SupportedLanguages);
  }

  //
  // If there are not enough resources for the supported languages string, then return a StringId of 0
  //
  if (AllocatedLanguages == NULL) {
    return (EFI_STRING_ID)(0);
  }

  Status = EFI_INVALID_PARAMETER;
  //
  // Loop through each language that the string supports
  //
  for (Supported = AllocatedLanguages; *Supported != '\0'; ) {
    //
    // Cache a pointer to the beginning of the current language in the list of languages
    //
    Language = Supported;

    //
    // Search for the next language separator and replace it with a Null-terminator
    //
    for ( ; *Supported != 0 && *Supported != ';'; Supported++) {
    }

    if (*Supported != 0) {
      *(Supported++) = '\0';
    }

    if ((SupportedLanguages == NULL) && (AsciiStrnCmp (Language, UEFI_CONFIG_LANG, AsciiStrLen (UEFI_CONFIG_LANG)) == 0)) {
      //
      // Skip string package used for keyword protocol.
      //
      continue;
    }

    //
    // If StringId is 0, then call NewString().  Otherwise, call SetString()
    //
    if (StringId == (EFI_STRING_ID)(0)) {
      Status = gHiiString->NewString (gHiiString, HiiHandle, &StringId, Language, NULL, String, NULL);
    } else {
      Status = gHiiString->SetString (gHiiString, HiiHandle, StringId, Language, String, NULL);
    }

    //
    // If there was an error, then break out of the loop and return a StringId of 0
    //
    if (EFI_ERROR (Status)) {
      break;
    }
  }

  //
  // Free the buffer of supported languages
  //
  FreePool (AllocatedLanguages);

  if (EFI_ERROR (Status)) {
    return (EFI_STRING_ID)(0);
  } else {
    return StringId;
  }
}

/**
  Retrieves a string from a string package names by GUID in a specific language.
  If the language is not specified, then a string from a string package in the
  current platform  language is retrieved.  If the string can not be retrieved
  using the specified language or the current platform language, then the string
  is retrieved from the string package in the first language the string package
  supports.  The returned string is allocated using AllocatePool().  The caller
  is responsible for freeing the allocated buffer using FreePool().

  If PackageListGuid is NULL, then ASSERT().
  If StringId is 0, then ASSERT.

  @param[in]  PackageListGuid  The GUID of a package list that was previously
                               registered in the HII Database.
  @param[in]  StringId         The identifier of the string to retrieved from the
                               string package associated with PackageListGuid.
  @param[in]  Language         The language of the string to retrieve.  If this
                               parameter is NULL, then the current platform
                               language is used.  The format of Language must
                               follow the language format assumed the HII Database.

  @retval NULL   The package list specified by PackageListGuid is not present in the
                 HII Database.
  @retval NULL   The string specified by StringId is not present in the string package.
  @retval Other  The string was returned.

**/
EFI_STRING
EFIAPI
HiiGetPackageString (
  IN CONST EFI_GUID  *PackageListGuid,
  IN EFI_STRING_ID   StringId,
  IN CONST CHAR8     *Language  OPTIONAL
  )
{
  EFI_HII_HANDLE  *HiiHandleBuffer;
  EFI_HII_HANDLE  HiiHandle;

  ASSERT (PackageListGuid != NULL);

  HiiHandleBuffer = HiiGetHiiHandles (PackageListGuid);
  if (HiiHandleBuffer == NULL) {
    return NULL;
  }

  HiiHandle = HiiHandleBuffer[0];
  FreePool (HiiHandleBuffer);

  return HiiGetString (HiiHandle, StringId, Language);
}

/**
  Retrieves a string from a string package in a specific language specified in Language
  or in the best lanaguage. See HiiGetStringEx () for the details.

  @param[in]  HiiHandle  A handle that was previously registered in the HII Database.
  @param[in]  StringId   The identifier of the string to retrieved from the string
                         package associated with HiiHandle.
  @param[in]  Language   The language of the string to retrieve.  If this parameter
                         is NULL, then the current platform language is used.  The
                         format of Language must follow the language format assumed
                         the HII Database.

  @retval NULL   The string specified by StringId is not present in the string package.
  @retval Other  The string was returned.

**/
EFI_STRING
EFIAPI
HiiGetString (
  IN EFI_HII_HANDLE  HiiHandle,
  IN EFI_STRING_ID   StringId,
  IN CONST CHAR8     *Language  OPTIONAL
  )
{
  return HiiGetStringEx (HiiHandle, StringId, Language, TRUE);
}

/**
  Retrieves a string from a string package in a specific language or in the best
  language at discretion of this function according to the priority of languages.
  TryBestLanguage is used to get the string in the best language or in the language
  specified in Language parameter. The behavior is,
  If TryBestLanguage is TRUE, this function looks for the best language for the string.
   - If the string can not be retrieved using the specified language or the current
     platform language, then the string is retrieved from the string package in the
     first language the string package supports.
  If TryBestLanguage is FALSE, Language must be specified for retrieving the string.

  The returned string is allocated using AllocatePool().  The caller is responsible
  for freeing the allocated buffer using FreePool().

  If HiiHandle is NULL, then ASSERT().
  If StringId is 0, then ASSET.
  If TryBestLanguage is FALE and Language is NULL, then ASSERT().

  @param[in]  HiiHandle         A handle that was previously registered in the HII Database.
  @param[in]  StringId          The identifier of the string to retrieved from the string
                                package associated with HiiHandle.
  @param[in]  Language          The language of the string to retrieve.  If this parameter
                                is NULL, then the current platform language is used.  The
                                format of Language must follow the language format assumed
                                the HII Database.
  @param[in]  TryBestLanguage   If TRUE, try to get the best matching language from all
                                supported languages.If FALSE, the Language must be assigned
                                for the StringID.

  @retval NULL   The string specified by StringId is not present in the string package.
  @retval Other  The string was returned.

**/
EFI_STRING
EFIAPI
HiiGetStringEx (
  IN EFI_HII_HANDLE  HiiHandle,
  IN EFI_STRING_ID   StringId,
  IN CONST CHAR8     *Language  OPTIONAL,
  IN BOOLEAN         TryBestLanguage
  )
{
  EFI_STATUS  Status;
  UINTN       StringSize;
  CHAR16      TempString;
  EFI_STRING  String;
  CHAR8       *SupportedLanguages;
  CHAR8       *PlatformLanguage;
  CHAR8       *BestLanguage;

  ASSERT (HiiHandle != NULL);
  ASSERT (StringId != 0);
  //
  // Language must be specified if TryBestLanguage = FALSE.
  //
  ASSERT (!(!TryBestLanguage && Language == NULL));
  //
  // Initialize all allocated buffers to NULL
  //
  SupportedLanguages = NULL;
  PlatformLanguage   = NULL;
  BestLanguage       = NULL;
  String             = NULL;

  //
  // Get the languages that the package specified by HiiHandle supports
  //
  SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
  if (SupportedLanguages == NULL) {
    goto Error;
  }

  //
  // Get the current platform language setting
  //
  GetEfiGlobalVariable2 (L"PlatformLang", (VOID **)&PlatformLanguage, NULL);

  //
  // If Languag is NULL, then set it to an empty string, so it will be
  // skipped by GetBestLanguage()
  //
  if (Language == NULL) {
    Language = "";
  }

  if (TryBestLanguage) {
    //
    // Get the best matching language from SupportedLanguages
    //
    BestLanguage = GetBestLanguage (
                     SupportedLanguages,
                     FALSE,                                             // RFC 4646 mode
                     Language,                                          // Highest priority
                     PlatformLanguage != NULL ? PlatformLanguage : "",  // Next highest priority
                     SupportedLanguages,                                // Lowest priority
                     NULL
                     );
    if (BestLanguage == NULL) {
      goto Error;
    }
  } else {
    BestLanguage = (CHAR8 *)Language;
  }

  //
  // Retrieve the size of the string in the string package for the BestLanguage
  //
  StringSize = 0;
  Status     = gHiiString->GetString (
                             gHiiString,
                             BestLanguage,
                             HiiHandle,
                             StringId,
                             &TempString,
                             &StringSize,
                             NULL
                             );
  //
  // If GetString() returns EFI_SUCCESS for a zero size,
  // then there are no supported languages registered for HiiHandle.  If GetString()
  // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present
  // in the HII Database
  //
  if (Status != EFI_BUFFER_TOO_SMALL) {
    goto Error;
  }

  //
  // Allocate a buffer for the return string
  //
  String = AllocateZeroPool (StringSize);
  if (String == NULL) {
    goto Error;
  }

  //
  // Retrieve the string from the string package
  //
  Status = gHiiString->GetString (
                         gHiiString,
                         BestLanguage,
                         HiiHandle,
                         StringId,
                         String,
                         &StringSize,
                         NULL
                         );
  if (EFI_ERROR (Status)) {
    //
    // Free the buffer and return NULL if the supported languages can not be retrieved.
    //
    FreePool (String);
    String = NULL;
  }

Error:
  //
  // Free allocated buffers
  //
  if (SupportedLanguages != NULL) {
    FreePool (SupportedLanguages);
  }

  if (PlatformLanguage != NULL) {
    FreePool (PlatformLanguage);
  }

  if (TryBestLanguage && (BestLanguage != NULL)) {
    FreePool (BestLanguage);
  }

  //
  // Return the Null-terminated Unicode string
  //
  return String;
}
