/** @file
  AML Tree Iterator.

  Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <AmlNodeDefines.h>
#include <Tree/AmlTreeIterator.h>

#include <AmlCoreInterface.h>
#include <Tree/AmlTreeTraversal.h>

/** Iterator to traverse the tree.

  This is an internal structure.
*/
typedef struct AmlTreeInternalIterator {
  /// External iterator structure, containing the external APIs.
  /// Must be the first field.
  AML_TREE_ITERATOR         Iterator;

  // Note: The following members of this structure are opaque to the users
  //       of the Tree iterator APIs.

  /// Pointer to the node on which the iterator has been initialized.
  CONST  AML_NODE_HEADER    *InitialNode;

  /// Pointer to the current node.
  CONST  AML_NODE_HEADER    *CurrentNode;

  /// Iteration mode.
  /// Allow to choose how to traverse the tree/choose which node is next.
  EAML_ITERATOR_MODE        Mode;
} AML_TREE_ITERATOR_INTERNAL;

/** Get the current node of an iterator.

  @param  [in]  Iterator  Pointer to an iterator.
  @param  [out] OutNode   Pointer holding the current node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlIteratorGetNode (
  IN  AML_TREE_ITERATOR  *Iterator,
  OUT AML_NODE_HEADER    **OutNode
  )
{
  AML_TREE_ITERATOR_INTERNAL  *InternalIterator;

  InternalIterator = (AML_TREE_ITERATOR_INTERNAL *)Iterator;

  // CurrentNode can be NULL, but InitialNode cannot.
  if ((OutNode == NULL)                                       ||
      (InternalIterator == NULL)                              ||
      (InternalIterator->Mode <= EAmlIteratorUnknown)         ||
      (InternalIterator->Mode >= EAmlIteratorModeMax)         ||
      !IS_AML_NODE_VALID (InternalIterator->InitialNode)      ||
      ((InternalIterator->CurrentNode != NULL)                &&
       !IS_AML_NODE_VALID (InternalIterator->CurrentNode)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  *OutNode = (AML_NODE_HEADER *)InternalIterator->CurrentNode;

  return EFI_SUCCESS;
}

/** Move the current node of the iterator to the next node,
    according to the iteration mode selected.

  If NextNode is not NULL, return the next node.

  @param  [in]  Iterator    Pointer to an iterator.
  @param  [out] NextNode    If not NULL, updated to the next node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlIteratorGetNextLinear (
  IN  AML_TREE_ITERATOR  *Iterator,
  OUT AML_NODE_HEADER    **NextNode
  )
{
  AML_TREE_ITERATOR_INTERNAL  *InternalIterator;

  InternalIterator = (AML_TREE_ITERATOR_INTERNAL *)Iterator;

  // CurrentNode can be NULL, but InitialNode cannot.
  if ((InternalIterator == NULL)                              ||
      (InternalIterator->Mode != EAmlIteratorLinear)          ||
      !IS_AML_NODE_VALID (InternalIterator->InitialNode)      ||
      !IS_AML_NODE_VALID (InternalIterator->CurrentNode))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Get the next node according to the iteration mode.
  InternalIterator->CurrentNode = AmlGetNextNode (
                                    InternalIterator->CurrentNode
                                    );

  if (NextNode != NULL) {
    *NextNode = (AML_NODE_HEADER *)InternalIterator->CurrentNode;
  }

  return EFI_SUCCESS;
}

/** Move the current node of the iterator to the previous node,
    according to the iteration mode selected.

  If PrevNode is not NULL, return the previous node.

  @param  [in]  Iterator    Pointer to an iterator.
  @param  [out] PrevNode    If not NULL, updated to the previous node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlIteratorGetPreviousLinear (
  IN  AML_TREE_ITERATOR  *Iterator,
  OUT AML_NODE_HEADER    **PrevNode
  )
{
  AML_TREE_ITERATOR_INTERNAL  *InternalIterator;

  InternalIterator = (AML_TREE_ITERATOR_INTERNAL *)Iterator;

  // CurrentNode can be NULL, but InitialNode cannot.
  if ((InternalIterator == NULL)                              ||
      (InternalIterator->Mode != EAmlIteratorLinear)          ||
      !IS_AML_NODE_VALID (InternalIterator->InitialNode)      ||
      !IS_AML_NODE_VALID (InternalIterator->CurrentNode))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Get the previous node according to the iteration mode.
  InternalIterator->CurrentNode = AmlGetPreviousNode (
                                    InternalIterator->CurrentNode
                                    );
  if (PrevNode != NULL) {
    *PrevNode = (AML_NODE_HEADER *)InternalIterator->CurrentNode;
  }

  return EFI_SUCCESS;
}

/** Move the current node of the iterator to the next node,
    according to the iteration mode selected.

  If NextNode is not NULL, return the next node.

  @param  [in]  Iterator    Pointer to an iterator.
  @param  [out] NextNode    If not NULL, updated to the next node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlIteratorGetNextBranch (
  IN  AML_TREE_ITERATOR  *Iterator,
  OUT AML_NODE_HEADER    **NextNode
  )
{
  AML_TREE_ITERATOR_INTERNAL  *InternalIterator;
  AML_NODE_HEADER             *Node;

  InternalIterator = (AML_TREE_ITERATOR_INTERNAL *)Iterator;

  // CurrentNode can be NULL, but InitialNode cannot.
  if ((InternalIterator == NULL)                              ||
      (InternalIterator->Mode != EAmlIteratorBranch)          ||
      !IS_AML_NODE_VALID (InternalIterator->InitialNode)      ||
      !IS_AML_NODE_VALID (InternalIterator->CurrentNode))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Node = AmlGetNextNode (InternalIterator->CurrentNode);
  // Check whether NextNode is a sibling of InitialNode.
  if (AmlGetParent (Node) ==
      AmlGetParent ((AML_NODE_HEADER *)InternalIterator->InitialNode))
  {
    Node = NULL;
  }

  InternalIterator->CurrentNode = Node;

  if (NextNode != NULL) {
    *NextNode = Node;
  }

  return EFI_SUCCESS;
}

/** Move the current node of the iterator to the previous node,
    according to the iteration mode selected.

  If PrevNode is not NULL, return the previous node.

  @param  [in]  Iterator    Pointer to an iterator.
  @param  [out] PrevNode    If not NULL, updated to the previous node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlIteratorGetPreviousBranch (
  IN  AML_TREE_ITERATOR  *Iterator,
  OUT AML_NODE_HEADER    **PrevNode
  )
{
  AML_TREE_ITERATOR_INTERNAL  *InternalIterator;
  AML_NODE_HEADER             *Node;

  InternalIterator = (AML_TREE_ITERATOR_INTERNAL *)Iterator;

  // CurrentNode can be NULL, but InitialNode cannot.
  if ((InternalIterator == NULL)                              ||
      (InternalIterator->Mode != EAmlIteratorBranch)          ||
      !IS_AML_NODE_VALID (InternalIterator->InitialNode)      ||
      !IS_AML_NODE_VALID (InternalIterator->CurrentNode))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Node = AmlGetPreviousNode (InternalIterator->CurrentNode);
  // Check whether PreviousNode is a sibling of InitialNode.
  if (AmlGetParent (Node) ==
      AmlGetParent ((AML_NODE_HEADER *)InternalIterator->InitialNode))
  {
    Node = NULL;
  }

  InternalIterator->CurrentNode = Node;

  if (PrevNode != NULL) {
    *PrevNode = Node;
  }

  return EFI_SUCCESS;
}

/** Initialize an iterator.

  Note: The caller must call AmlDeleteIterator () to free the memory
        allocated for the iterator.

  @param  [in]  Node          Pointer to the node.
  @param  [in]  IteratorMode  Selected mode to traverse the tree.
  @param  [out] IteratorPtr   Pointer holding the created iterator.

  @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
AmlInitializeIterator (
  IN   AML_NODE_HEADER     *Node,
  IN   EAML_ITERATOR_MODE  IteratorMode,
  OUT  AML_TREE_ITERATOR   **IteratorPtr
  )
{
  AML_TREE_ITERATOR_INTERNAL  *InternalIterator;

  if (!IS_AML_NODE_VALID (Node)             ||
      (IteratorMode <= EAmlIteratorUnknown) ||
      (IteratorMode >= EAmlIteratorModeMax) ||
      (IteratorPtr == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  *IteratorPtr     = NULL;
  InternalIterator = (AML_TREE_ITERATOR_INTERNAL *)AllocateZeroPool (
                                                     sizeof (
                                                             AML_TREE_ITERATOR_INTERNAL
                                                             )
                                                     );
  if (InternalIterator == NULL) {
    ASSERT (0);
    return EFI_OUT_OF_RESOURCES;
  }

  InternalIterator->InitialNode      = Node;
  InternalIterator->CurrentNode      = Node;
  InternalIterator->Mode             = IteratorMode;
  InternalIterator->Iterator.GetNode = AmlIteratorGetNode;

  switch (InternalIterator->Mode) {
    case EAmlIteratorLinear:
    {
      InternalIterator->Iterator.GetNext     = AmlIteratorGetNextLinear;
      InternalIterator->Iterator.GetPrevious = AmlIteratorGetPreviousLinear;
      break;
    }
    case EAmlIteratorBranch:
    {
      InternalIterator->Iterator.GetNext     = AmlIteratorGetNextBranch;
      InternalIterator->Iterator.GetPrevious = AmlIteratorGetPreviousBranch;
      break;
    }
    default:
    {
      ASSERT (0);
      FreePool (InternalIterator);
      return EFI_INVALID_PARAMETER;
    }
  } // switch

  *IteratorPtr = &InternalIterator->Iterator;

  return EFI_SUCCESS;
}

/** Delete an iterator.

  Note: The caller must have first initialized the iterator with the
        AmlInitializeIterator () function.

  @param  [in]  Iterator  Pointer to an iterator.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlDeleteIterator (
  IN  AML_TREE_ITERATOR  *Iterator
  )
{
  if (Iterator == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  FreePool (Iterator);

  return EFI_SUCCESS;
}
