/** @file
  AML Clone.

  Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <AmlNodeDefines.h>

#include <AmlCoreInterface.h>
#include <Tree/AmlNode.h>
#include <Tree/AmlTree.h>

/** Clone a node.

  This function does not clone the children nodes.
  The cloned node returned is not attached to any tree.

  @param  [in]  Node        Pointer to a node.
  @param  [out] ClonedNode  Pointer holding the cloned node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCloneNode (
  IN  AML_NODE_HEADER  *Node,
  OUT AML_NODE_HEADER  **ClonedNode
  )
{
  EFI_STATUS  Status;

  AML_OBJECT_NODE  *ObjectNode;
  AML_DATA_NODE    *DataNode;
  AML_ROOT_NODE    *RootNode;

  if (!IS_AML_NODE_VALID (Node) ||
      (ClonedNode == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  if (IS_AML_DATA_NODE (Node)) {
    DataNode = (AML_DATA_NODE *)Node;
    Status   = AmlCreateDataNode (
                 DataNode->DataType,
                 DataNode->Buffer,
                 DataNode->Size,
                 (AML_DATA_NODE **)ClonedNode
                 );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
    }
  } else if (IS_AML_OBJECT_NODE (Node)) {
    ObjectNode = (AML_OBJECT_NODE *)Node;

    Status = AmlCreateObjectNode (
               ObjectNode->AmlByteEncoding,
               ObjectNode->PkgLen,
               (AML_OBJECT_NODE **)ClonedNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
    }
  } else if (IS_AML_ROOT_NODE (Node)) {
    RootNode = (AML_ROOT_NODE *)Node;

    Status = AmlCreateRootNode (
               RootNode->SdtHeader,
               (AML_ROOT_NODE **)ClonedNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
    }
  } else {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  return Status;
}

/** Clone a node and its children (clone a tree branch).

  The cloned branch returned is not attached to any tree.

  @param  [in]  Node        Pointer to a node.
                            Node is the head of the branch to clone.
  @param  [out] ClonedNode  Pointer holding the head of the created cloned
                            branch.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCloneTree (
  IN  AML_NODE_HEADER  *Node,
  OUT AML_NODE_HEADER  **ClonedNode
  )
{
  EFI_STATUS  Status;

  AML_NODE_HEADER  *HeadNode;
  AML_NODE_HEADER  *ClonedChildNode;
  AML_NODE_HEADER  *FixedArgNode;

  EAML_PARSE_INDEX  Index;
  EAML_PARSE_INDEX  MaxIndex;

  LIST_ENTRY  *StartLink;
  LIST_ENTRY  *CurrentLink;

  if (!IS_AML_NODE_VALID (Node) ||
      (ClonedNode == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Status = AmlCloneNode (Node, &HeadNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Clone the fixed arguments and bind them to their parent.
  MaxIndex = (EAML_PARSE_INDEX)AmlGetFixedArgumentCount (
                                 (AML_OBJECT_NODE *)Node
                                 );
  for (Index = EAmlParseIndexTerm0; Index < MaxIndex; Index++) {
    FixedArgNode = AmlGetFixedArgument ((AML_OBJECT_NODE *)Node, Index);
    if (FixedArgNode == NULL) {
      Status = EFI_INVALID_PARAMETER;
      ASSERT (0);
      goto error_handler;
    }

    // Clone child.
    Status = AmlCloneTree (
               FixedArgNode,
               &ClonedChildNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      goto error_handler;
    }

    // Bind child.
    Status = AmlSetFixedArgument (
               (AML_OBJECT_NODE *)HeadNode,
               Index,
               ClonedChildNode
               );
    if (EFI_ERROR (Status)) {
      AmlDeleteTree (ClonedChildNode);
      ASSERT (0);
      goto error_handler;
    }
  } // for

  // Clone the variable arguments and bind them to their parent.
  StartLink = AmlNodeGetVariableArgList (Node);
  if (StartLink != NULL) {
    CurrentLink = StartLink->ForwardLink;
    while (CurrentLink != StartLink) {
      // Clone child.
      Status = AmlCloneTree ((AML_NODE_HEADER *)CurrentLink, &ClonedChildNode);
      if (EFI_ERROR (Status)) {
        ASSERT (0);
        goto error_handler;
      }

      // Bind child.
      Status = AmlVarListAddTailInternal (
                 HeadNode,
                 ClonedChildNode
                 );
      if (EFI_ERROR (Status)) {
        AmlDeleteTree (ClonedChildNode);
        ASSERT (0);
        goto error_handler;
      }

      CurrentLink = CurrentLink->ForwardLink;
    } // while
  }

  *ClonedNode = HeadNode;
  return Status;

error_handler:
  *ClonedNode = NULL;

  if (HeadNode != NULL) {
    AmlDeleteTree (HeadNode);
  }

  return Status;
}
