/** @file
  Dynamic Platform Info Repository

  Copyright (c) 2021, Arm Limited. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

  @par Glossary:
    - Cm or CM   - Configuration Manager
    - Obj or OBJ - Object
**/

#include <Protocol/ConfigurationManagerProtocol.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>

#include "CmObjectTokenFixer.h"
#include "DynamicPlatRepoInternal.h"
#include "TokenGenerator.h"

/** Allocate a CM_OBJ_NODE.

  @param [in]  CmObjDesc  CmObj to wrap in a node.
                          All the fields of the CmObj (Data field included),
                          are copied.
  @param [in]  Token      Token to assign to this CmObj/node.
  @param [out] ObjNode    Allocated ObjNode.

  @retval EFI_SUCCESS           Success.
  @retval EFI_INVALID_PARAMETER A parameter is invalid.
  @retval EFI_OUT_OF_RESOURCES  An allocation has failed.
**/
STATIC
EFI_STATUS
EFIAPI
AllocCmObjNode (
  IN  CONST CM_OBJ_DESCRIPTOR  *CmObjDesc,
  IN        CM_OBJECT_TOKEN    Token,
  OUT       CM_OBJ_NODE        **ObjNode
  )
{
  CM_OBJ_NODE        *Node;
  CM_OBJ_DESCRIPTOR  *Desc;

  if ((CmObjDesc == NULL) || (ObjNode == NULL)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Node = AllocateZeroPool (sizeof (CM_OBJ_NODE));
  if (Node == NULL) {
    ASSERT (0);
    return EFI_OUT_OF_RESOURCES;
  }

  // Initialise the list head.
  InitializeListHead (&Node->Link);
  Node->Token    = Token;
  Desc           = &Node->CmObjDesc;
  Desc->ObjectId = CmObjDesc->ObjectId;
  Desc->Size     = CmObjDesc->Size;
  Desc->Count    = CmObjDesc->Count;

  // Allocate and copy the CmObject Data.
  Desc->Data = AllocateCopyPool (CmObjDesc->Size, CmObjDesc->Data);
  if (Desc->Data == NULL) {
    FreePool (Node);
    ASSERT (0);
    return EFI_OUT_OF_RESOURCES;
  }

  *ObjNode = Node;
  return EFI_SUCCESS;
}

/** Free a CM_OBJ_NODE.

  @param [in]  ObjNode    ObjNode to free.

  @retval EFI_SUCCESS           Success.
  @retval EFI_INVALID_PARAMETER A parameter is invalid.
**/
STATIC
EFI_STATUS
EFIAPI
FreeCmObjNode (
  IN  CM_OBJ_NODE  *ObjNode
  )
{
  CM_OBJ_DESCRIPTOR  *Desc;

  if (ObjNode == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Unlink Node
  RemoveEntryList (&ObjNode->Link);

  Desc = &ObjNode->CmObjDesc;
  if (Desc->Data != NULL) {
    FreePool (Desc->Data);
  }

  FreePool (ObjNode);
  return EFI_SUCCESS;
}

/** Add an object to the dynamic platform repository.

  @param [in]  This       This dynamic platform repository.
  @param [in]  CmObjDesc  CmObj to add. The data is copied.
  @param [out] Token      If not NULL, token allocated to this CmObj.

  @retval EFI_SUCCESS           Success.
  @retval EFI_INVALID_PARAMETER A parameter is invalid.
  @retval EFI_OUT_OF_RESOURCES  An allocation has failed.
**/
EFI_STATUS
EFIAPI
DynPlatRepoAddObject (
  IN        DYNAMIC_PLATFORM_REPOSITORY_INFO  *This,
  IN  CONST CM_OBJ_DESCRIPTOR                 *CmObjDesc,
  OUT       CM_OBJECT_TOKEN                   *Token OPTIONAL
  )
{
  EFI_STATUS       Status;
  CM_OBJ_NODE      *ObjNode;
  CM_OBJECT_ID     ArmNamespaceObjId;
  CM_OBJECT_TOKEN  NewToken;

  // The dynamic repository must be able to receive objects.
  if ((This == NULL)      ||
      (CmObjDesc == NULL) ||
      (This->RepoState != DynRepoTransient))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Check the CmObjDesc:
  //  - only Arm objects are supported for now.
  //  - only EArmObjCmRef objects can be added as arrays.
  ArmNamespaceObjId = GET_CM_OBJECT_ID (CmObjDesc->ObjectId);
  if ((CmObjDesc->Size == 0)              ||
      (CmObjDesc->Count == 0)             ||
      (ArmNamespaceObjId >= EArmObjMax)   ||
      ((CmObjDesc->Count > 1)  && (ArmNamespaceObjId != EArmObjCmRef))  ||
      (GET_CM_NAMESPACE_ID (CmObjDesc->ObjectId) != EObjNameSpaceArm))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Generate a token.
  NewToken = GenerateToken ();

  // Create an ObjNode.
  Status = AllocCmObjNode (CmObjDesc, NewToken, &ObjNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Fixup self-token if necessary.
  Status = FixupCmObjectSelfToken (&ObjNode->CmObjDesc, NewToken);
  if (EFI_ERROR (Status)) {
    FreeCmObjNode (ObjNode);
    ASSERT (0);
    return Status;
  }

  // Add to link list.
  InsertTailList (&This->ArmCmObjList[ArmNamespaceObjId], &ObjNode->Link);
  This->ObjectCount += 1;

  if (Token != NULL) {
    *Token = NewToken;
  }

  return EFI_SUCCESS;
}

/** Group lists of CmObjNode from the ArmNameSpace to one array.

  @param [in]  This         This dynamic platform repository.
  @param [in]  ArmObjIndex  Index in EARM_OBJECT_ID
                            (must be < EArmObjMax).

  @retval EFI_SUCCESS           Success.
  @retval EFI_INVALID_PARAMETER A parameter is invalid.
  @retval EFI_BUFFER_TOO_SMALL    Buffer too small.
  @retval EFI_OUT_OF_RESOURCES  An allocation has failed.
**/
STATIC
EFI_STATUS
EFIAPI
GroupCmObjNodes (
  IN  DYNAMIC_PLATFORM_REPOSITORY_INFO  *This,
  IN  UINT32                            ArmObjIndex
  )
{
  EFI_STATUS         Status;
  UINTN              Count;
  UINTN              Size;
  UINT32             CmObjId;
  UINT8              *GroupedData;
  UINT8              *Data;
  CM_OBJ_DESCRIPTOR  *CmObjDesc;
  LIST_ENTRY         *ListHead;
  LIST_ENTRY         *Link;

  if ((This == NULL)  ||
      (ArmObjIndex >= EArmObjMax))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Count    = 0;
  Size     = 0;
  CmObjId  = CREATE_CM_ARM_OBJECT_ID (ArmObjIndex);
  ListHead = &This->ArmCmObjList[ArmObjIndex];
  Link     = GetFirstNode (ListHead);

  // Compute the total count and size of the CmObj in the list.
  while (Link != ListHead) {
    CmObjDesc = &((CM_OBJ_NODE *)Link)->CmObjDesc;

    if (CmObjDesc->ObjectId != CmObjId) {
      ASSERT (0);
      return EFI_INVALID_PARAMETER;
    }

    if ((CmObjDesc->Count != 1) && (ArmObjIndex != EArmObjCmRef)) {
      // We expect each descriptor to contain an individual object.
      // EArmObjCmRef objects are counted as groups, so +1 as well.
      ASSERT (0);
      return EFI_INVALID_PARAMETER;
    }

    Count++;
    Size += CmObjDesc->Size;

    // Next Link
    Link = GetNextNode (ListHead, Link);
  } // while

  if (Count == 0) {
    // No objects found.
    return EFI_SUCCESS;
  }

  GroupedData = AllocateZeroPool (Size);
  if (GroupedData == NULL) {
    ASSERT (0);
    return EFI_OUT_OF_RESOURCES;
  }

  // Copy the Object Data and add to the TokenMapper.
  Data = GroupedData;
  Link = GetFirstNode (ListHead);
  while (Link != ListHead) {
    CmObjDesc = &((CM_OBJ_NODE *)Link)->CmObjDesc;
    CopyMem (Data, CmObjDesc->Data, CmObjDesc->Size);

    // Add the object to the Token Mapper.
    // Note: The CmObject Data field of objects in the Token Mapper point
    //       to the memory in the GroupedData array.
    Status = TokenMapperAddObject (
               &This->TokenMapper,
               ((CM_OBJ_NODE *)Link)->Token,
               CmObjDesc->ObjectId,
               CmObjDesc->Size,
               Data
               );
    if (EFI_ERROR (Status)) {
      FreePool (GroupedData);
      return Status;
    }

    Data += CmObjDesc->Size;
    Link  = GetNextNode (ListHead, Link);
  } // while

  CmObjDesc           = &This->ArmCmObjArray[ArmObjIndex];
  CmObjDesc->ObjectId = CmObjId;
  CmObjDesc->Size     = Size;
  CmObjDesc->Count    = Count;
  CmObjDesc->Data     = GroupedData;

  return Status;
}

/** Finalise the dynamic repository.

  Finalising means:
   - Preventing any further objects from being added.
   - Allowing to get objects from the dynamic repository
     (not possible before a call to this function).

  @param [in]  This       This dynamic platform repository.

  @retval EFI_SUCCESS           Success.
  @retval EFI_ALREADY_STARTED   Instance already initialised.
  @retval EFI_INVALID_PARAMETER A parameter is invalid.
  @retval EFI_BUFFER_TOO_SMALL  Buffer too small.
  @retval EFI_OUT_OF_RESOURCES  An allocation has failed.
**/
EFI_STATUS
EFIAPI
DynamicPlatRepoFinalise (
  IN  DYNAMIC_PLATFORM_REPOSITORY_INFO  *This
  )
{
  EFI_STATUS  Status;
  UINTN       ArmObjIndex;

  if ((This == NULL)  ||
      (This->RepoState != DynRepoTransient))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Prevent any further objects from being added.
  This->RepoState = DynRepoFinalized;

  // Initialise the token mapper.
  Status = TokenMapperInitialise (&This->TokenMapper, This->ObjectCount);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // For each CM_OBJECT_ID:
  //  - Convert the list of nodes to an array
  //    (the array is wrapped in a CmObjDesc).
  //  - Add the Token/CmObj binding to the token mapper.
  for (ArmObjIndex = 0; ArmObjIndex < EArmObjMax; ArmObjIndex++) {
    Status = GroupCmObjNodes (This, ArmObjIndex);
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      // Free the TokenMapper.
      // Ignore the returned Status since we already failed.
      TokenMapperShutdown (&This->TokenMapper);
      return Status;
    }
  } // for

  return EFI_SUCCESS;
}

/** Get a CmObj from the dynamic repository.

  @param [in]      This        Pointer to the Dynamic Platform Repository.
  @param [in]      CmObjectId  The Configuration Manager Object ID.
  @param [in]      Token       An optional token identifying the object. If
                               unused this must be CM_NULL_TOKEN.
  @param [in, out] CmObjDesc   Pointer to the Configuration Manager Object
                               descriptor describing the requested Object.

  @retval EFI_SUCCESS           Success.
  @retval EFI_INVALID_PARAMETER A parameter is invalid.
  @retval EFI_NOT_FOUND         The required object information is not found.
**/
EFI_STATUS
EFIAPI
DynamicPlatRepoGetObject (
  IN      DYNAMIC_PLATFORM_REPOSITORY_INFO  *This,
  IN      CM_OBJECT_ID                      CmObjectId,
  IN      CM_OBJECT_TOKEN                   Token OPTIONAL,
  IN  OUT CM_OBJ_DESCRIPTOR                 *CmObjDesc
  )
{
  EFI_STATUS         Status;
  CM_OBJ_DESCRIPTOR  *Desc;
  CM_OBJECT_ID       ArmNamespaceObjId;

  if ((This == NULL)      ||
      (CmObjDesc == NULL) ||
      (This->RepoState != DynRepoFinalized))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  ArmNamespaceObjId = GET_CM_OBJECT_ID (CmObjectId);
  if (ArmNamespaceObjId >= EArmObjMax) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  if (Token != CM_NULL_TOKEN) {
    // Search in the Token Mapper and return the object.
    Status = TokenMapperGetObject (
               &This->TokenMapper,
               Token,
               CmObjectId,
               CmObjDesc
               );
    ASSERT_EFI_ERROR (Status);
    return Status;
  }

  if (ArmNamespaceObjId == EArmObjCmRef) {
    // EArmObjCmRef object must be requested using a valid token.
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Desc = &This->ArmCmObjArray[ArmNamespaceObjId];

  // Nothing here.
  if (Desc->Count == 0) {
    return EFI_NOT_FOUND;
  } else {
    // Return the full array.
    CmObjDesc->ObjectId = Desc->ObjectId;
    CmObjDesc->Size     = Desc->Size;
    CmObjDesc->Data     = Desc->Data;
    CmObjDesc->Count    = Desc->Count;
  }

  return EFI_SUCCESS;
}

/** Initialize the dynamic platform repository.

  @param [out]  DynPlatRepo   If success, contains the initialised dynamic
                              platform repository.

  @retval EFI_SUCCESS           Success.
  @retval EFI_INVALID_PARAMETER A parameter is invalid.
  @retval EFI_OUT_OF_RESOURCES  An allocation has failed.
**/
EFI_STATUS
EFIAPI
DynamicPlatRepoInit (
  OUT DYNAMIC_PLATFORM_REPOSITORY_INFO  **DynPlatRepo
  )
{
  UINTN                             Index;
  DYNAMIC_PLATFORM_REPOSITORY_INFO  *Repo;

  if (DynPlatRepo == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Repo = AllocateZeroPool (sizeof (DYNAMIC_PLATFORM_REPOSITORY_INFO));
  if (Repo == NULL) {
    ASSERT (0);
    return EFI_OUT_OF_RESOURCES;
  }

  // Initialise the CmObject List.
  for (Index = 0; Index < EArmObjMax; Index++) {
    InitializeListHead (&Repo->ArmCmObjList[Index]);
  }

  Repo->ObjectCount = 0;
  Repo->RepoState   = DynRepoTransient;

  *DynPlatRepo = Repo;

  return EFI_SUCCESS;
}

/** Shutdown the dynamic platform repository.

  Free all the memory allocated for the dynamic platform repository.

  @param [in]  DynPlatRepo    The dynamic platform repository.

  @retval EFI_INVALID_PARAMETER A parameter is invalid.
  @retval EFI_SUCCESS           Success.
**/
EFI_STATUS
EFIAPI
DynamicPlatRepoShutdown (
  IN  DYNAMIC_PLATFORM_REPOSITORY_INFO  *DynPlatRepo
  )
{
  EFI_STATUS         Status;
  UINT32             Index;
  LIST_ENTRY         *ListHead;
  CM_OBJ_DESCRIPTOR  *CmObjDesc;
  VOID               *Data;

  if (DynPlatRepo == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Free the list of objects.
  for (Index = 0; Index < EArmObjMax; Index++) {
    // Free all the nodes with this object Id.
    ListHead = &DynPlatRepo->ArmCmObjList[Index];
    while (!IsListEmpty (ListHead)) {
      FreeCmObjNode ((CM_OBJ_NODE *)GetFirstNode (ListHead));
    } // while
  } // for

  // Free the arrays.
  CmObjDesc = DynPlatRepo->ArmCmObjArray;
  for (Index = 0; Index < EArmObjMax; Index++) {
    Data = CmObjDesc[Index].Data;
    if (Data != NULL) {
      FreePool (Data);
    }
  } // for

  // Free the TokenMapper
  Status = TokenMapperShutdown (&DynPlatRepo->TokenMapper);
  ASSERT_EFI_ERROR (Status);
  FreePool (DynPlatRepo);
  return Status;
}
