/** @file
  AML Tree.

  Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Tree/AmlTree.h>

#include <AmlCoreInterface.h>
#include <Tree/AmlNode.h>
#include <Tree/AmlTreeTraversal.h>
#include <Utils/AmlUtility.h>

/** Get the parent node of the input Node.

  @param [in] Node  Pointer to a node.

  @return The parent node of the input Node.
          NULL otherwise.
**/
AML_NODE_HEADER *
EFIAPI
AmlGetParent (
  IN  AML_NODE_HEADER  *Node
  )
{
  if (IS_AML_DATA_NODE (Node) ||
      IS_AML_OBJECT_NODE (Node))
  {
    return Node->Parent;
  }

  return NULL;
}

/** Get the root node from any node of the tree.
    This is done by climbing up the tree until the root node is reached.

  @param  [in]  Node    Pointer to a node.

  @return The root node of the tree.
          NULL if error.
**/
AML_ROOT_NODE *
EFIAPI
AmlGetRootNode (
  IN  CONST AML_NODE_HEADER  *Node
  )
{
  if (!IS_AML_NODE_VALID (Node)) {
    ASSERT (0);
    return NULL;
  }

  while (!IS_AML_ROOT_NODE (Node)) {
    Node = Node->Parent;
    if (!IS_AML_NODE_VALID (Node)) {
      ASSERT (0);
      return NULL;
    }
  }

  return (AML_ROOT_NODE *)Node;
}

/** Get the node at the input Index in the fixed argument list of the input
    ObjectNode.

  @param  [in]  ObjectNode  Pointer to an object node.
  @param  [in]  Index       The Index of the fixed argument to get.

  @return The node at the input Index in the fixed argument list
          of the input ObjectNode.
          NULL otherwise, e.g. if the node is not an object node, or no
          node is available at this Index.
**/
AML_NODE_HEADER *
EFIAPI
AmlGetFixedArgument (
  IN  AML_OBJECT_NODE   *ObjectNode,
  IN  EAML_PARSE_INDEX  Index
  )
{
  if (IS_AML_OBJECT_NODE (ObjectNode)) {
    if (Index < (EAML_PARSE_INDEX)AmlGetFixedArgumentCount (ObjectNode)) {
      return ObjectNode->FixedArgs[Index];
    }
  }

  return NULL;
}

/** Check whether the input Node is in the fixed argument list of its parent
    node.

  If so, IndexPtr contains this Index.

  @param  [in]  Node          Pointer to a Node.
  @param  [out] IndexPtr      Pointer holding the Index of the Node in
                              its parent's fixed argument list.

  @retval TRUE   The node is a fixed argument and the index
                 in IndexPtr is valid.
  @retval FALSE  The node is not a fixed argument.
**/
BOOLEAN
EFIAPI
AmlIsNodeFixedArgument (
  IN  CONST  AML_NODE_HEADER   *Node,
  OUT        EAML_PARSE_INDEX  *IndexPtr
  )
{
  AML_NODE_HEADER  *ParentNode;

  EAML_PARSE_INDEX  Index;
  EAML_PARSE_INDEX  MaxIndex;

  if ((IndexPtr == NULL)               ||
      (!IS_AML_DATA_NODE (Node)        &&
       !IS_AML_OBJECT_NODE (Node)))
  {
    ASSERT (0);
    return FALSE;
  }

  ParentNode = AmlGetParent ((AML_NODE_HEADER *)Node);
  if (IS_AML_ROOT_NODE (ParentNode)) {
    return FALSE;
  } else if (IS_AML_DATA_NODE (ParentNode)) {
    // Tree is inconsistent.
    ASSERT (0);
    return FALSE;
  }

  // Check whether the Node is in the fixed argument list.
  MaxIndex = (EAML_PARSE_INDEX)AmlGetFixedArgumentCount (
                                 (AML_OBJECT_NODE *)ParentNode
                                 );
  for (Index = EAmlParseIndexTerm0; Index < MaxIndex; Index++) {
    if (AmlGetFixedArgument ((AML_OBJECT_NODE *)ParentNode, Index) == Node) {
      *IndexPtr = Index;
      return TRUE;
    }
  }

  return FALSE;
}

/** Set the fixed argument of the ObjectNode at the Index to the NewNode.

  It is the caller's responsibility to save the old node, if desired,
  otherwise the reference to the old node will be lost.
  If NewNode is not NULL, set its parent to ObjectNode.

  @param  [in]  ObjectNode    Pointer to an object node.
  @param  [in]  Index         Index in the fixed argument list of
                              the ObjectNode to set.
  @param  [in]  NewNode       Pointer to the NewNode.
                              Can be NULL, a data node or an object node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlSetFixedArgument (
  IN  AML_OBJECT_NODE   *ObjectNode,
  IN  EAML_PARSE_INDEX  Index,
  IN  AML_NODE_HEADER   *NewNode
  )
{
  if (IS_AML_OBJECT_NODE (ObjectNode)                                     &&
      (Index <= (EAML_PARSE_INDEX)AmlGetFixedArgumentCount (ObjectNode))  &&
      ((NewNode == NULL)                                                  ||
       IS_AML_OBJECT_NODE (NewNode)                                       ||
       IS_AML_DATA_NODE (NewNode)))
  {
    ObjectNode->FixedArgs[Index] = NewNode;

    // If NewNode is a data node or an object node, set its parent.
    if (NewNode != NULL) {
      NewNode->Parent = (AML_NODE_HEADER *)ObjectNode;
    }

    return EFI_SUCCESS;
  }

  ASSERT (0);
  return EFI_INVALID_PARAMETER;
}

/** If the given AML_NODE_HEADER has a variable list of arguments,
    return a pointer to this list.
    Return NULL otherwise.

  @param  [in]  Node  Pointer to the AML_NODE_HEADER to check.

  @return The list of variable arguments if there is one.
          NULL otherwise.
**/
LIST_ENTRY *
EFIAPI
AmlNodeGetVariableArgList (
  IN  CONST AML_NODE_HEADER  *Node
  )
{
  if (IS_AML_ROOT_NODE (Node)) {
    return &(((AML_ROOT_NODE *)Node)->VariableArgs);
  } else if (IS_AML_OBJECT_NODE (Node)) {
    return &(((AML_OBJECT_NODE *)Node)->VariableArgs);
  }

  return NULL;
}

/** Remove the Node from its parent's variable list of arguments.

  The function will fail if the Node is in its parent's fixed
  argument list.
  The Node is not deleted. The deletion is done separately
  from the removal.

  @param  [in]  Node  Pointer to a Node.
                      Must be a data node or an object node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlRemoveNodeFromVarArgList (
  IN  AML_NODE_HEADER  *Node
  )
{
  EFI_STATUS       Status;
  AML_NODE_HEADER  *ParentNode;
  UINT32           Size;

  if ((!IS_AML_DATA_NODE (Node) &&
       !IS_AML_OBJECT_NODE (Node)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  ParentNode = AmlGetParent (Node);
  if (!IS_AML_ROOT_NODE (ParentNode)  &&
      !IS_AML_OBJECT_NODE (ParentNode))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Check the node is in its parent variable list of arguments.
  if (!IsNodeInList (
         AmlNodeGetVariableArgList (ParentNode),
         &Node->Link
         ))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Unlink Node from the tree.
  RemoveEntryList (&Node->Link);
  InitializeListHead (&Node->Link);
  Node->Parent = NULL;

  // Get the size of the node removed.
  Status = AmlComputeSize (Node, &Size);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Propagate the information.
  Status = AmlPropagateInformation (ParentNode, FALSE, Size, 1);
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/** Detach the Node from the tree.

  The function will fail if the Node is in its parent's fixed
  argument list.
  The Node is not deleted. The deletion is done separately
  from the removal.

  @param  [in]  Node  Pointer to a Node.
                      Must be a data node or an object node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlDetachNode (
  IN  AML_NODE_HEADER  *Node
  )
{
  return AmlRemoveNodeFromVarArgList (Node);
}

/** Add the NewNode to the head of the variable list of arguments
    of the ParentNode.

  @param  [in]  ParentNode  Pointer to the parent node.
                            Must be a root or an object node.
  @param  [in]  NewNode     Pointer to the node to add.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlVarListAddHead (
  IN  AML_NODE_HEADER  *ParentNode,
  IN  AML_NODE_HEADER  *NewNode
  )
{
  EFI_STATUS  Status;
  UINT32      NewSize;
  LIST_ENTRY  *ChildrenList;

  // Check arguments and that NewNode is not already attached to a tree.
  // ParentNode != Data Node AND NewNode != Root Node AND NewNode != attached.
  if ((!IS_AML_ROOT_NODE (ParentNode)     &&
       !IS_AML_OBJECT_NODE (ParentNode))  ||
      (!IS_AML_DATA_NODE (NewNode)        &&
       !IS_AML_OBJECT_NODE (NewNode))     ||
      !AML_NODE_IS_DETACHED (NewNode))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Insert it at the head of the list.
  ChildrenList = AmlNodeGetVariableArgList (ParentNode);
  if (ChildrenList == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  InsertHeadList (ChildrenList, &NewNode->Link);
  NewNode->Parent = ParentNode;

  // Get the size of the NewNode.
  Status = AmlComputeSize (NewNode, &NewSize);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Propagate the new information.
  Status = AmlPropagateInformation (ParentNode, TRUE, NewSize, 1);
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/** Add the NewNode to the tail of the variable list of arguments
    of the ParentNode.

  NOTE: This is an internal function which does not propagate the size
        when a new node is added.

  @param  [in]  ParentNode  Pointer to the parent node.
                            Must be a root or an object node.
  @param  [in]  NewNode     Pointer to the node to add.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlVarListAddTailInternal (
  IN  AML_NODE_HEADER  *ParentNode,
  IN  AML_NODE_HEADER  *NewNode
  )
{
  LIST_ENTRY  *ChildrenList;

  // Check arguments and that NewNode is not already attached to a tree.
  // ParentNode != Data Node AND NewNode != Root Node AND NewNode != attached.
  if ((!IS_AML_ROOT_NODE (ParentNode)     &&
       !IS_AML_OBJECT_NODE (ParentNode))  ||
      (!IS_AML_DATA_NODE (NewNode)        &&
       !IS_AML_OBJECT_NODE (NewNode))     ||
      !AML_NODE_IS_DETACHED (NewNode))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Insert it at the tail of the list.
  ChildrenList = AmlNodeGetVariableArgList (ParentNode);
  if (ChildrenList == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  InsertTailList (ChildrenList, &NewNode->Link);
  NewNode->Parent = ParentNode;

  return EFI_SUCCESS;
}

/** Add the NewNode to the tail of the variable list of arguments
    of the ParentNode.

  @param  [in]  ParentNode  Pointer to the parent node.
                            Must be a root or an object node.
  @param  [in]  NewNode     Pointer to the node to add.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlVarListAddTail (
  IN  AML_NODE_HEADER  *ParentNode,
  IN  AML_NODE_HEADER  *NewNode
  )
{
  EFI_STATUS  Status;
  UINT32      NewSize;

  // Add the NewNode and check arguments.
  Status = AmlVarListAddTailInternal (ParentNode, NewNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Get the size of the NewNode.
  Status = AmlComputeSize (NewNode, &NewSize);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Propagate the new information.
  Status = AmlPropagateInformation (ParentNode, TRUE, NewSize, 1);
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/** Add the NewNode before the Node in the list of variable
    arguments of the Node's parent.

  @param  [in]  Node      Pointer to a node.
                          Must be a root or an object node.
  @param  [in]  NewNode   Pointer to the node to add.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlVarListAddBefore (
  IN  AML_NODE_HEADER  *Node,
  IN  AML_NODE_HEADER  *NewNode
  )
{
  EFI_STATUS       Status;
  AML_NODE_HEADER  *ParentNode;
  UINT32           NewSize;

  // Check arguments and that NewNode is not already attached to a tree.
  if ((!IS_AML_DATA_NODE (NewNode)        &&
       !IS_AML_OBJECT_NODE (NewNode))     ||
      !AML_NODE_IS_DETACHED (NewNode))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  ParentNode = AmlGetParent (Node);
  if (!IS_AML_ROOT_NODE (ParentNode)    &&
      !IS_AML_OBJECT_NODE (ParentNode))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Insert it before the input Node.
  InsertTailList (&Node->Link, &NewNode->Link);
  NewNode->Parent = ParentNode;

  // Get the size of the NewNode.
  Status = AmlComputeSize (NewNode, &NewSize);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Propagate the new information.
  Status = AmlPropagateInformation (ParentNode, TRUE, NewSize, 1);
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/** Add the NewNode after the Node in the variable list of arguments
    of the Node's parent.

  @param  [in]  Node      Pointer to a node.
                          Must be a root or an object node.
  @param  [in]  NewNode   Pointer to the node to add.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlVarListAddAfter (
  IN  AML_NODE_HEADER  *Node,
  IN  AML_NODE_HEADER  *NewNode
  )
{
  EFI_STATUS       Status;
  AML_NODE_HEADER  *ParentNode;
  UINT32           NewSize;

  // Check arguments and that NewNode is not already attached to a tree.
  if ((!IS_AML_DATA_NODE (NewNode)        &&
       !IS_AML_OBJECT_NODE (NewNode))     ||
      !AML_NODE_IS_DETACHED (NewNode))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  ParentNode = AmlGetParent (Node);
  if (!IS_AML_ROOT_NODE (ParentNode)    &&
      !IS_AML_OBJECT_NODE (ParentNode))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Insert the new node after the input Node.
  InsertHeadList (&Node->Link, &NewNode->Link);
  NewNode->Parent = ParentNode;

  // Get the size of the NewNode.
  Status = AmlComputeSize (NewNode, &NewSize);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Propagate the new information.
  Status = AmlPropagateInformation (ParentNode, TRUE, NewSize, 1);
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/** Append a Resource Data node to the BufferOpNode.

  The Resource Data node is added at the end of the variable
  list of arguments of the BufferOpNode, but before the End Tag.
  If no End Tag is found, the function returns an error.

  @param  [in]  BufferOpNode  Buffer node containing resource data elements.
  @param  [in]  NewRdNode     The new Resource Data node to add.

  @retval  EFI_SUCCESS            The function completed successfully.
  @retval  EFI_INVALID_PARAMETER  Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlAppendRdNode (
  IN  AML_OBJECT_NODE  *BufferOpNode,
  IN  AML_DATA_NODE    *NewRdNode
  )
{
  EFI_STATUS     Status;
  AML_DATA_NODE  *LastRdNode;

  if (!AmlNodeCompareOpCode (BufferOpNode, AML_BUFFER_OP, 0)  ||
      !IS_AML_DATA_NODE (NewRdNode)                           ||
      (NewRdNode->DataType != EAmlNodeDataTypeResourceData))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // To avoid re-computing checksums, if a new resource data elements is
  // added/removed/modified in a list of resource data elements, the AmlLib
  // resets the checksum to 0.
  // It is possible to have only one Resource Data in a BufferOp with
  // no EndTag, but it should not be possible to add a new Resource Data
  // in the list in this case.
  Status = AmlSetRdListCheckSum (BufferOpNode, 0);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Get the last Resource data node in the variable list of argument of the
  // BufferOp node. This must be an EndTag, otherwise setting the checksum
  // would have failed.
  LastRdNode = (AML_DATA_NODE *)AmlGetPreviousVariableArgument (
                                  (AML_NODE_HEADER *)BufferOpNode,
                                  NULL
                                  );
  if ((LastRdNode == NULL)             ||
      !IS_AML_DATA_NODE (LastRdNode)   ||
      (LastRdNode->DataType != EAmlNodeDataTypeResourceData))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Add NewRdNode before the EndTag.
  Status = AmlVarListAddBefore (
             (AML_NODE_HEADER *)LastRdNode,
             (AML_NODE_HEADER *)NewRdNode
             )
  ;
  ASSERT_EFI_ERROR (Status);
  return Status;
}

/** Replace the fixed argument at the Index of the ParentNode with the NewNode.

  Note: This function unlinks the OldNode from the tree. It is the callers
        responsibility to delete the OldNode if needed.

  @param  [in]  ParentNode  Pointer to the parent node.
                            Must be an object node.
  @param  [in]  Index       Index of the fixed argument to replace.
  @param  [in]  NewNode     The new node to insert.
                            Must be an object node or a data node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlReplaceFixedArgument (
  IN  AML_OBJECT_NODE   *ParentNode,
  IN  EAML_PARSE_INDEX  Index,
  IN  AML_NODE_HEADER   *NewNode
  )
{
  EFI_STATUS  Status;

  AML_NODE_HEADER   *OldNode;
  UINT32            NewSize;
  UINT32            OldSize;
  AML_PARSE_FORMAT  FixedArgType;

  // Check arguments and that NewNode is not already attached to a tree.
  if (!IS_AML_OBJECT_NODE (ParentNode)  ||
      (!IS_AML_DATA_NODE (NewNode)      &&
       !IS_AML_OBJECT_NODE (NewNode))   ||
      !AML_NODE_IS_DETACHED (NewNode))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Perform some compatibility checks between NewNode and OldNode.
  FixedArgType = ParentNode->AmlByteEncoding->Format[Index];
  switch (FixedArgType) {
    case EAmlFieldPkgLen:
    {
      // A FieldPkgLen can only have a parent node with the
      // AML_IS_FIELD_ELEMENT flag.
      if (!AmlNodeHasAttribute (
             (AML_OBJECT_NODE *)ParentNode,
             AML_HAS_FIELD_LIST
             ))
      {
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
      }

      // Fall through.
    }

    case EAmlUInt8:
    case EAmlUInt16:
    case EAmlUInt32:
    case EAmlUInt64:
    case EAmlName:
    case EAmlString:
    {
      // A uint, a name, a string and a FieldPkgLen can only be replaced by a
      // data node of the same type.
      // Note: This condition might be too strict, but safer.
      if (!IS_AML_DATA_NODE (NewNode) ||
          (((AML_DATA_NODE *)NewNode)->DataType !=
           AmlTypeToNodeDataType (FixedArgType)))
      {
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
      }

      break;
    }

    case EAmlObject:
    {
      // If it's an object node, the grammar is too complex to do any check.
      break;
    }

    case EAmlNone:
    default:
    {
      ASSERT (0);
      return EFI_INVALID_PARAMETER;
      break;
    }
  } // switch

  // Replace the OldNode with the NewNode.
  OldNode = AmlGetFixedArgument (ParentNode, Index);
  if (!IS_AML_NODE_VALID (OldNode)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Unlink the old node.
  // Note: This function unlinks the OldNode from the tree. It is the callers
  //       responsibility to delete the OldNode if needed.
  OldNode->Parent = NULL;

  Status = AmlSetFixedArgument (ParentNode, Index, NewNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Get the size of the OldNode.
  Status = AmlComputeSize (OldNode, &OldSize);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Get the size of the NewNode.
  Status = AmlComputeSize (NewNode, &NewSize);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Propagate the new information.
  Status = AmlPropagateInformation (
             (AML_NODE_HEADER *)ParentNode,
             (NewSize > OldSize) ? TRUE : FALSE,
             (NewSize > OldSize) ? (NewSize - OldSize) : (OldSize - NewSize),
             0
             );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/** Replace the OldNode, which is in a variable list of arguments,
    with the NewNode.

  Note: This function unlinks the OldNode from the tree. It is the callers
        responsibility to delete the OldNode if needed.

  @param  [in]  OldNode   Pointer to the node to replace.
                          Must be a data node or an object node.
  @param  [in]  NewNode   The new node to insert.
                          Must be a data node or an object node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlReplaceVariableArgument (
  IN  AML_NODE_HEADER  *OldNode,
  IN  AML_NODE_HEADER  *NewNode
  )
{
  EFI_STATUS        Status;
  UINT32            NewSize;
  UINT32            OldSize;
  EAML_PARSE_INDEX  Index;

  AML_DATA_NODE    *NewDataNode;
  AML_NODE_HEADER  *ParentNode;
  LIST_ENTRY       *NextLink;

  // Check arguments, that NewNode is not already attached to a tree,
  // and that OldNode is attached and not in a fixed list of arguments.
  if ((!IS_AML_DATA_NODE (OldNode)      &&
       !IS_AML_OBJECT_NODE (OldNode))   ||
      (!IS_AML_DATA_NODE (NewNode)      &&
       !IS_AML_OBJECT_NODE (NewNode))   ||
      !AML_NODE_IS_DETACHED (NewNode)   ||
      AML_NODE_IS_DETACHED (OldNode)    ||
      AmlIsNodeFixedArgument (OldNode, &Index))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  ParentNode = AmlGetParent (OldNode);
  if (!IS_AML_ROOT_NODE (ParentNode)    &&
      !IS_AML_OBJECT_NODE (ParentNode))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  NewDataNode = (AML_DATA_NODE *)NewNode;

  // Check attributes if the parent node is an object node.
  if (IS_AML_OBJECT_NODE (ParentNode)) {
    // A child node of a node with the HAS_CHILD flag must be either a
    // data node or an object node. This has already been checked. So,
    // check for other cases.

    if (AmlNodeHasAttribute ((AML_OBJECT_NODE *)ParentNode, AML_HAS_BYTE_LIST)) {
      if (!IS_AML_DATA_NODE (NewNode)                       ||
          ((NewDataNode->DataType != EAmlNodeDataTypeRaw)   &&
           (NewDataNode->DataType != EAmlNodeDataTypeResourceData)))
      {
        // A child node of a node with the BYTE_LIST flag must be a data node,
        // containing raw data or a resource data.
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
      }
    } else if (AmlNodeHasAttribute (
                 (AML_OBJECT_NODE *)ParentNode,
                 AML_HAS_FIELD_LIST
                 ))
    {
      if (!AmlNodeHasAttribute (
             (CONST AML_OBJECT_NODE *)NewNode,
             AML_IS_FIELD_ELEMENT
             ))
      {
        // A child node of a node with the FIELD_LIST flag must be an object
        // node with AML_IS_FIELD_ELEMENT flag.
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
      }
    }
  } else {
    // Parent node is a root node.
    // A root node cannot have a data node as its child.
    if (!IS_AML_DATA_NODE (NewNode)) {
      ASSERT (0);
      return EFI_INVALID_PARAMETER;
    }
  }

  // Unlink OldNode from the tree.
  NextLink = RemoveEntryList (&OldNode->Link);
  InitializeListHead (&OldNode->Link);
  OldNode->Parent = NULL;

  // Add the NewNode.
  InsertHeadList (NextLink, &NewNode->Link);
  NewNode->Parent = ParentNode;

  // Get the size of the OldNode.
  Status = AmlComputeSize (OldNode, &OldSize);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Get the size of the NewNode.
  Status = AmlComputeSize (NewNode, &NewSize);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Propagate the new information.
  Status = AmlPropagateInformation (
             ParentNode,
             (NewSize > OldSize) ? TRUE : FALSE,
             (NewSize > OldSize) ? (NewSize - OldSize) : (OldSize - NewSize),
             0
             );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/** Replace the OldNode by the NewNode.

  Note: This function unlinks the OldNode from the tree. It is the callers
        responsibility to delete the OldNode if needed.

  @param  [in]  OldNode   Pointer to the node to replace.
                          Must be a data node or an object node.
  @param  [in]  NewNode   The new node to insert.
                          Must be a data node or an object node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlReplaceArgument (
  IN  AML_NODE_HEADER  *OldNode,
  IN  AML_NODE_HEADER  *NewNode
  )
{
  EFI_STATUS        Status;
  AML_NODE_HEADER   *ParentNode;
  EAML_PARSE_INDEX  Index;

  // Check arguments and that NewNode is not already attached to a tree.
  if ((!IS_AML_DATA_NODE (OldNode)      &&
       !IS_AML_OBJECT_NODE (OldNode))   ||
      (!IS_AML_DATA_NODE (NewNode)      &&
       !IS_AML_OBJECT_NODE (NewNode))   ||
      !AML_NODE_IS_DETACHED (NewNode))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // ParentNode can be a root node or an object node.
  ParentNode = AmlGetParent (OldNode);
  if (!IS_AML_ROOT_NODE (ParentNode)  &&
      !IS_AML_OBJECT_NODE (ParentNode))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  if (AmlIsNodeFixedArgument (OldNode, &Index)) {
    // OldNode is in its parent's fixed argument list at the Index.
    Status = AmlReplaceFixedArgument (
               (AML_OBJECT_NODE *)ParentNode,
               Index,
               NewNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }
  } else {
    // OldNode is not in its parent's fixed argument list.
    // It must be in its variable list of arguments.
    Status = AmlReplaceVariableArgument (OldNode, NewNode);
    ASSERT_EFI_ERROR (Status);
  }

  return Status;
}

/** Delete a Node and its children.

  The Node must be removed from the tree first,
  or must be the root node.

  @param  [in]  Node  Pointer to the node to delete.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlDeleteTree (
  IN  AML_NODE_HEADER  *Node
  )
{
  EFI_STATUS  Status;

  EAML_PARSE_INDEX  Index;
  EAML_PARSE_INDEX  MaxIndex;

  AML_NODE_HEADER  *Arg;
  LIST_ENTRY       *StartLink;
  LIST_ENTRY       *CurrentLink;
  LIST_ENTRY       *NextLink;

  // Check that the node being deleted is unlinked.
  // When removing the node, its parent pointer and
  // its lists data structure are reset with
  // InitializeListHead. Thus it must be detached
  // from the tree to avoid memory leaks.
  if (!IS_AML_NODE_VALID (Node)  ||
      !AML_NODE_IS_DETACHED (Node))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // 1. Recursively detach and delete the fixed arguments.
  //    Iterate through the fixed list of arguments.
  if (IS_AML_OBJECT_NODE (Node)) {
    MaxIndex = (EAML_PARSE_INDEX)AmlGetFixedArgumentCount (
                                   (AML_OBJECT_NODE *)Node
                                   );
    for (Index = EAmlParseIndexTerm0; Index < MaxIndex; Index++) {
      Arg = AmlGetFixedArgument ((AML_OBJECT_NODE *)Node, Index);
      if (Arg == NULL) {
        // A fixed argument is missing. The tree is inconsistent.
        // Note: During CodeGeneration, the fixed arguments should be set
        //       with an incrementing index, and then the variable arguments
        //       should be added. This allows to free as many nodes as
        //       possible if a crash occurs.
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
      }

      // Remove the node from the fixed argument list.
      Arg->Parent = NULL;
      Status      = AmlSetFixedArgument ((AML_OBJECT_NODE *)Node, Index, NULL);
      if (EFI_ERROR (Status)) {
        ASSERT (0);
        return Status;
      }

      Status = AmlDeleteTree (Arg);
      if (EFI_ERROR (Status)) {
        ASSERT (0);
        return Status;
      }
    }
  }

  // 2. Recursively detach and delete the variable arguments.
  //    Iterate through the variable list of arguments.
  StartLink = AmlNodeGetVariableArgList (Node);
  if (StartLink != NULL) {
    NextLink = StartLink->ForwardLink;
    while (NextLink != StartLink) {
      CurrentLink = NextLink;

      // Unlink the node from the tree.
      NextLink = RemoveEntryList (CurrentLink);
      InitializeListHead (CurrentLink);
      ((AML_NODE_HEADER *)CurrentLink)->Parent = NULL;

      Status = AmlDeleteTree ((AML_NODE_HEADER *)CurrentLink);
      if (EFI_ERROR (Status)) {
        ASSERT (0);
        return Status;
      }
    } // while
  }

  // 3. Delete the node.
  Status = AmlDeleteNode (Node);
  ASSERT_EFI_ERROR (Status);

  return Status;
}
