/** @file
  Metadata Object Library.

  Copyright (c) 2025, Arm Limited. All rights reserved.
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Base.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <ConfigurationManagerObject.h>

#include "MetadataObj.h"

/** Array of METADATA_STATIC_INFO. */
STATIC METADATA_STATIC_INFO  mMetadataStaticInfo[MetadataTypeMax] = {
  // MetadataTypeUid
  {
    sizeof (METADATA_OBJ_UID),
  },
  // MetadataTypeProximityDomain
  {
    sizeof (METADATA_OBJ_PROXIMITY_DOMAIN),
  },
};

/** Initialize the Metadata Root.

  @param[out]  Root  If success, Root of the Metadata information.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Out of resources.
**/
EFI_STATUS
EFIAPI
MetadataInitializeHandle (
  OUT METADATA_ROOT_HANDLE  *Root
  )
{
  METADATA_ROOT  *OutRoot;
  UINT32         Index;

  if (Root == NULL) {
    ASSERT (Root != NULL);
    return EFI_INVALID_PARAMETER;
  }

  OutRoot = AllocateZeroPool (sizeof (*OutRoot));
  if (OutRoot == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  for (Index = 0; Index < MetadataTypeMax; Index++) {
    InitializeListHead (&OutRoot->MetadataList[Index].List);
  }

  *Root = OutRoot;
  return EFI_SUCCESS;
}

/** Free the Metadata Root.

  @param[in]  Root  Root of the Metadata information to free.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Out of resources.
**/
EFI_STATUS
EFIAPI
MetadataFreeHandle (
  IN METADATA_ROOT_HANDLE  Root
  )
{
  if (Root == NULL) {
    ASSERT (Root != NULL);
    return EFI_INVALID_PARAMETER;
  }

  FreePool (Root);
  return EFI_SUCCESS;
}

/** Allocate a METADATA_ENTRY.

  @param[in]  Type          METADATA_TYPE of the entry to allocate.
  @param[in]  Token         Token uniquely identifying an entry among other
                            objects with the input METADATA_TYPE.
  @param[in]  Metadata      Metadata to associate to the (Type/Token) pair.
                            The data is copied.
  @param[in]  MetadataSize  Size of the input Metadata.
  @param[out] OutMdEntry    If success, contains the created METADATA_ENTRY.

  @retval EFI_SUCCESS             Success.
  @retval EFI_OUT_OF_RESOURCES    Out of resources.
**/
STATIC
EFI_STATUS
EFIAPI
AllocateMetadataEntry (
  IN  METADATA_TYPE    Type,
  IN  CM_OBJECT_TOKEN  Token,
  IN  VOID             *Metadata,
  IN  UINT32           MetadataSize,
  OUT METADATA_ENTRY   **OutMdEntry
  )
{
  METADATA_ENTRY  *Entry;

  ASSERT (Type < MetadataTypeMax);
  ASSERT (Token != CM_NULL_TOKEN);
  ASSERT (Metadata != NULL);
  ASSERT (MetadataSize == mMetadataStaticInfo[Type].ExpectedSize);
  ASSERT (OutMdEntry != NULL);

  Entry = AllocateZeroPool (sizeof (*Entry));
  if (Entry == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Entry->Type     = Type;
  Entry->Token    = Token;
  Entry->Metadata = AllocateCopyPool (MetadataSize, Metadata);
  if (Entry->Metadata == NULL) {
    FreePool (Entry);
    return EFI_OUT_OF_RESOURCES;
  }

  InitializeListHead (&Entry->List);

  *OutMdEntry = Entry;
  return EFI_SUCCESS;
}

/** Find a METADATA_ENTRY with a matching (Type/Token).

  @param[in]  Root          Root of the Metadata information.
  @param[in]  Type          METADATA_TYPE of the entry to allocate.
  @param[in]  Token         Token uniquely identifying an entry among other
                            objects with the input METADATA_TYPE.
  @param[out] OutMdEntry    If success, contains the METADATA_ENTRY with
                            a matching (Type/Token).

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_NOT_FOUND           Not found.
**/
STATIC
EFI_STATUS
EFIAPI
MetadataFindEntry (
  IN  METADATA_ROOT    *Root,
  IN  METADATA_TYPE    Type,
  IN  CM_OBJECT_TOKEN  Token,
  OUT METADATA_ENTRY   **OutMdEntry
  )
{
  LIST_ENTRY      *ListHead;
  LIST_ENTRY      *Link;
  METADATA_ENTRY  *Entry;

  if ((Type >= MetadataTypeMax) ||
      (Token == CM_NULL_TOKEN) ||
      (OutMdEntry == NULL))
  {
    ASSERT (Type < MetadataTypeMax);
    ASSERT (Token != CM_NULL_TOKEN);
    ASSERT (OutMdEntry != NULL);
    return EFI_INVALID_PARAMETER;
  }

  ListHead = &Root->MetadataList[Type].List;
  Link     = GetFirstNode (ListHead);

  while (Link != ListHead) {
    Entry = (METADATA_ENTRY *)Link;

    if (Entry->Token == Token) {
      break;
    }

    Link = GetNextNode (ListHead, Link);
  }

  // No matching token.
  if (Link == ListHead) {
    return EFI_NOT_FOUND;
  }

  *OutMdEntry = Entry;
  return EFI_SUCCESS;
}

/** Attach some Metadata to a (Type/Token) pair.

  @param[in]  Root          Root of the Metadata information.
  @param[in]  Type          METADATA_TYPE of the entry to allocate.
  @param[in]  Token         Token uniquely identifying an entry among other
                            objects with the input METADATA_TYPE.
  @param[in]  Metadata      Metadata to associate to the (Type/Token) pair.
                            The data is copied.
  @param[in]  MetadataSize  Size of the input Metadata.

  @retval EFI_SUCCESS     Success.
  @retval EFI_ALREADY_STARTED   (Type/Token) pair is already present.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_NOT_FOUND   Not found.
**/
EFI_STATUS
EFIAPI
MetadataAdd (
  IN  METADATA_ROOT_HANDLE  Root,
  IN  METADATA_TYPE         Type,
  IN  CM_OBJECT_TOKEN       Token,
  IN  VOID                  *Metadata,
  IN  UINT32                MetadataSize
  )
{
  EFI_STATUS      Status;
  METADATA_ENTRY  *Entry;

  if ((Root == NULL)              ||
      (Type >= MetadataTypeMax)   ||
      (Token == CM_NULL_TOKEN)    ||
      (Metadata == NULL)          ||
      (MetadataSize != mMetadataStaticInfo[Type].ExpectedSize))
  {
    ASSERT (Root != NULL);
    ASSERT (Type < MetadataTypeMax);
    ASSERT (Token != CM_NULL_TOKEN);
    ASSERT (Metadata != NULL);
    ASSERT (MetadataSize == mMetadataStaticInfo[Type].ExpectedSize);
    return EFI_INVALID_PARAMETER;
  }

  Status = MetadataFindEntry (Root, Type, Token, &Entry);
  if (Status == EFI_SUCCESS) {
    // The (Type/Token) pair already exists.
    return EFI_ALREADY_STARTED;
  } else if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
    // Error other than not-found.
    ASSERT_EFI_ERROR (Status);
    return Status;
  }

  // If not-found, create an new entry.
  Status = AllocateMetadataEntry (Type, Token, Metadata, MetadataSize, &Entry);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return Status;
  }

  InsertTailList (&((METADATA_ROOT *)Root)->MetadataList[Type].List, &Entry->List);
  return Status;
}

/** Remove a (Type/Token) pair and its associated Metadata.

  @param[in]  Root          Root of the Metadata information.
  @param[in]  Type          METADATA_TYPE of the entry to remove.
  @param[in]  Token         Token uniquely identifying an entry among other
                            objects with the input METADATA_TYPE.

  @retval EFI_SUCCESS     Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_NOT_FOUND   Not found.
**/
EFI_STATUS
EFIAPI
MetadataRemove (
  IN  METADATA_ROOT_HANDLE  Root,
  IN  METADATA_TYPE         Type,
  IN  CM_OBJECT_TOKEN       Token
  )
{
  EFI_STATUS      Status;
  METADATA_ENTRY  *Entry;

  if ((Root == NULL)              ||
      (Type >= MetadataTypeMax)   ||
      (Token == CM_NULL_TOKEN))
  {
    ASSERT (Root != NULL);
    ASSERT (Type < MetadataTypeMax);
    ASSERT (Token != CM_NULL_TOKEN);
    return EFI_INVALID_PARAMETER;
  }

  Status = MetadataFindEntry (Root, Type, Token, &Entry);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return Status;
  }

  RemoveEntryList (&Entry->List);
  if (Entry->Metadata != NULL) {
    FreePool (Entry->Metadata);
  }

  FreePool (Entry);

  return EFI_SUCCESS;
}

/** Get the Metadata associated with an (Type/Token).

  @param[in]  Root          Root of the Metadata information.
  @param[in]  Type          METADATA_TYPE of the entry to get.
  @param[in]  Token         Token uniquely identifying an entry among other
                            objects with the input METADATA_TYPE.
  @param[out] Metadata      If success, contains the Metadata associated to the
                            input (Type/Token).
  @param[in]  MetadataSize  Size of the input Metadata.

  @retval EFI_SUCCESS     Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_NOT_FOUND   Not found.
**/
EFI_STATUS
EFIAPI
MetadataGet (
  IN  METADATA_ROOT_HANDLE  Root,
  IN  METADATA_TYPE         Type,
  IN  CM_OBJECT_TOKEN       Token,
  OUT VOID                  *Metadata,
  IN  UINT32                MetadataSize
  )
{
  EFI_STATUS      Status;
  METADATA_ENTRY  *Entry;

  if ((Root == NULL)              ||
      (Type >= MetadataTypeMax)   ||
      (Token == CM_NULL_TOKEN)    ||
      (Metadata == NULL)          ||
      (MetadataSize != mMetadataStaticInfo[Type].ExpectedSize))
  {
    ASSERT (Root != NULL);
    ASSERT (Type < MetadataTypeMax);
    ASSERT (Token != CM_NULL_TOKEN);
    ASSERT (Metadata != NULL);
    ASSERT (MetadataSize != mMetadataStaticInfo[Type].ExpectedSize);
    return EFI_INVALID_PARAMETER;
  }

  Status = MetadataFindEntry (Root, Type, Token, &Entry);
  if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
    // Error other than not-found.
    ASSERT_EFI_ERROR (Status);
    return Status;
  } else if (Status == EFI_NOT_FOUND) {
    return Status;
  }

  CopyMem (Metadata, Entry->Metadata, MetadataSize);
  return EFI_SUCCESS;
}

/** Iterate over the existing Metadata with the same Type.

  @param[in]  Root          Root of the Metadata information.
  @param[in]  Type            METADATA_TYPE to iterate over.
  @param[in]  PrevHandle    MetadataIterate () returns the Metadata handle
                            following PrevHandle.
                            If PrevHandle==NULL, the first Handle of the type
                            is returned.
                            If PrevHandle is the last Handle of the type,
                            NULL is returned.
  @param[out] Metadata      Metadata of the current Handle.
  @param[in]  MetadataSize  Size of the input Metadata.

  @return METADATA_HANDLE   The Metadata handle following PrevHandle.
**/
METADATA_HANDLE
EFIAPI
MetadataIterate (
  IN  METADATA_ROOT_HANDLE  Root,
  IN  METADATA_TYPE         Type,
  IN  METADATA_HANDLE       PrevHandle,
  OUT VOID                  *Metadata,
  IN  UINT32                MetadataSize
  )
{
  METADATA_ENTRY  *Entry;
  LIST_ENTRY      *ListHead;
  LIST_ENTRY      *Link;

  if ((Root == NULL)              ||
      (Type >= MetadataTypeMax)   ||
      (Metadata == NULL)          ||
      (MetadataSize != mMetadataStaticInfo[Type].ExpectedSize))
  {
    ASSERT (Root != NULL);
    ASSERT (Type < MetadataTypeMax);
    ASSERT (Metadata != NULL);
    ASSERT (MetadataSize == mMetadataStaticInfo[Type].ExpectedSize);
    return NULL;
  }

  ListHead = &((METADATA_ROOT *)Root)->MetadataList[Type].List;

  if (PrevHandle == NULL) {
    Link = GetFirstNode (ListHead);
  } else {
    Link = GetNextNode (ListHead, (LIST_ENTRY *)PrevHandle);
  }

  // End of the list.
  if (Link == ListHead) {
    Link = NULL;
  }

  Entry = (METADATA_ENTRY *)Link;

  if ((Entry != NULL) && (Entry->Metadata != NULL)) {
    CopyMem (Metadata, Entry->Metadata, mMetadataStaticInfo[Type].ExpectedSize);
  }

  return (METADATA_HANDLE)Link;
}
