/**
  Implement UnitTestLib assert services

  Copyright (c) Microsoft Corporation.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Uefi.h>
#include <UnitTestFrameworkTypes.h>
#include <Library/UnitTestLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/PrintLib.h>

extern BASE_LIBRARY_JUMP_BUFFER  gUnitTestJumpBuffer;

STATIC
EFI_STATUS
AddUnitTestFailure (
  IN OUT UNIT_TEST     *UnitTest,
  IN     CONST CHAR8   *FailureMessage,
  IN     FAILURE_TYPE  FailureType
  )
{
  //
  // Make sure that you're cooking with gas.
  //
  if ((UnitTest == NULL) || (FailureMessage == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  UnitTest->FailureType = FailureType;
  AsciiStrCpyS (
    &UnitTest->FailureMessage[0],
    UNIT_TEST_TESTFAILUREMSG_LENGTH,
    FailureMessage
    );

  return EFI_SUCCESS;
}

STATIC
VOID
EFIAPI
UnitTestLogFailure (
  IN FAILURE_TYPE  FailureType,
  IN CONST CHAR8   *Format,
  ...
  )
{
  UNIT_TEST_FRAMEWORK_HANDLE  FrameworkHandle;
  CHAR8                       LogString[UNIT_TEST_TESTFAILUREMSG_LENGTH];
  VA_LIST                     Marker;

  //
  // Get active Framework handle
  //
  FrameworkHandle = GetActiveFrameworkHandle ();
  if (FrameworkHandle == NULL) {
    DEBUG ((DEBUG_ERROR, "%a - FrameworkHandle not initialized\n", __func__));
    return;
  }

  //
  // Convert the message to an ASCII String
  //
  VA_START (Marker, Format);
  AsciiVSPrint (LogString, sizeof (LogString), Format, Marker);
  VA_END (Marker);

  //
  // Finally, add the string to the log.
  //
  AddUnitTestFailure (
    ((UNIT_TEST_FRAMEWORK *)FrameworkHandle)->CurrentTest,
    LogString,
    FailureType
    );

  LongJump (&gUnitTestJumpBuffer, 1);
}

/**
  If Expression is TRUE, then TRUE is returned.
  If Expression is FALSE, then an assert is triggered and the location of the
  assert provided by FunctionName, LineNumber, FileName, and Description are
  recorded and FALSE is returned.

  @param[in]  Expression    The BOOLEAN result of the expression evaluation.
  @param[in]  FunctionName  Null-terminated ASCII string of the function
                            executing the assert macro.
  @param[in]  LineNumber    The source file line number of the assert macro.
  @param[in]  FileName      Null-terminated ASCII string of the filename
                            executing the assert macro.
  @param[in]  Description   Null-terminated ASCII string of the expression being
                            evaluated.

  @retval  TRUE   Expression is TRUE.
  @retval  FALSE  Expression is FALSE.
**/
BOOLEAN
EFIAPI
UnitTestAssertTrue (
  IN BOOLEAN      Expression,
  IN CONST CHAR8  *FunctionName,
  IN UINTN        LineNumber,
  IN CONST CHAR8  *FileName,
  IN CONST CHAR8  *Description
  )
{
  if (!Expression) {
    UT_LOG_ERROR (
      "[ASSERT FAIL] %a:%d: Expression (%a) is not TRUE!\n",
      FileName,
      LineNumber,
      Description
      );
    UnitTestLogFailure (
      FAILURETYPE_ASSERTTRUE,
      "%a:%d: Expression (%a) is not TRUE!\n",
      FileName,
      LineNumber,
      Description
      );
  }

  return Expression;
}

/**
  If Expression is FALSE, then TRUE is returned.
  If Expression is TRUE, then an assert is triggered and the location of the
  assert provided by FunctionName, LineNumber, FileName, and Description are
  recorded and FALSE is returned.

  @param[in]  Expression    The BOOLEAN result of the expression evaluation.
  @param[in]  FunctionName  Null-terminated ASCII string of the function
                            executing the assert macro.
  @param[in]  LineNumber    The source file line number of the assert macro.
  @param[in]  FileName      Null-terminated ASCII string of the filename
                            executing the assert macro.
  @param[in]  Description   Null-terminated ASCII string of the expression being
                            evaluated.

  @retval  TRUE   Expression is FALSE.
  @retval  FALSE  Expression is TRUE.
**/
BOOLEAN
EFIAPI
UnitTestAssertFalse (
  IN BOOLEAN      Expression,
  IN CONST CHAR8  *FunctionName,
  IN UINTN        LineNumber,
  IN CONST CHAR8  *FileName,
  IN CONST CHAR8  *Description
  )
{
  if (Expression) {
    UT_LOG_ERROR (
      "[ASSERT FAIL] %a:%d: Expression (%a) is not FALSE!\n",
      FileName,
      LineNumber,
      Description
      );
    UnitTestLogFailure (
      FAILURETYPE_ASSERTFALSE,
      "%a:%d: Expression(%a) is not FALSE!\n",
      FileName,
      LineNumber,
      Description
      );
  }

  return !Expression;
}

/**
  If Status is not an EFI_ERROR(), then TRUE is returned.
  If Status is an EFI_ERROR(), then an assert is triggered and the location of
  the assert provided by FunctionName, LineNumber, FileName, and Description are
  recorded and FALSE is returned.

  @param[in]  Status        The EFI_STATUS value to evaluate.
  @param[in]  FunctionName  Null-terminated ASCII string of the function
                            executing the assert macro.
  @param[in]  LineNumber    The source file line number of the assert macro.
  @param[in]  FileName      Null-terminated ASCII string of the filename
                            executing the assert macro.
  @param[in]  Description   Null-terminated ASCII string of the status
                            expression being evaluated.

  @retval  TRUE   Status is not an EFI_ERROR().
  @retval  FALSE  Status is an EFI_ERROR().
**/
BOOLEAN
EFIAPI
UnitTestAssertNotEfiError (
  IN EFI_STATUS   Status,
  IN CONST CHAR8  *FunctionName,
  IN UINTN        LineNumber,
  IN CONST CHAR8  *FileName,
  IN CONST CHAR8  *Description
  )
{
  if (EFI_ERROR (Status)) {
    UT_LOG_ERROR (
      "[ASSERT FAIL] %a:%d: Status '%a' is EFI_ERROR (%r)!\n",
      FileName,
      LineNumber,
      Description,
      Status
      );
    UnitTestLogFailure (
      FAILURETYPE_ASSERTNOTEFIERROR,
      "%a:%d: Status '%a' is EFI_ERROR (%r)!\n",
      FileName,
      LineNumber,
      Description,
      Status
      );
  }

  return !EFI_ERROR (Status);
}

/**
  If ValueA is equal ValueB, then TRUE is returned.
  If ValueA is not equal to ValueB, then an assert is triggered and the location
  of the assert provided by FunctionName, LineNumber, FileName, DescriptionA,
  and DescriptionB are recorded and FALSE is returned.

  @param[in]  ValueA        64-bit value.
  @param[in]  ValueB        64-bit value.
  @param[in]  FunctionName  Null-terminated ASCII string of the function
                            executing the assert macro.
  @param[in]  LineNumber    The source file line number of the assert macro.
  @param[in]  FileName      Null-terminated ASCII string of the filename
                            executing the assert macro.
  @param[in]  DescriptionA  Null-terminated ASCII string that is a description
                            of ValueA.
  @param[in]  DescriptionB  Null-terminated ASCII string that is a description
                            of ValueB.

  @retval  TRUE   ValueA is equal to ValueB.
  @retval  FALSE  ValueA is not equal to ValueB.
**/
BOOLEAN
EFIAPI
UnitTestAssertEqual (
  IN UINT64       ValueA,
  IN UINT64       ValueB,
  IN CONST CHAR8  *FunctionName,
  IN UINTN        LineNumber,
  IN CONST CHAR8  *FileName,
  IN CONST CHAR8  *DescriptionA,
  IN CONST CHAR8  *DescriptionB
  )
{
  if (ValueA != ValueB) {
    UT_LOG_ERROR (
      "[ASSERT FAIL] %a:%d: Value %a != %a (%d != %d)!\n",
      FileName,
      LineNumber,
      DescriptionA,
      DescriptionB,
      ValueA,
      ValueB
      );
    UnitTestLogFailure (
      FAILURETYPE_ASSERTEQUAL,
      "%a:%d: Value %a != %a (%d != %d)!\n",
      FileName,
      LineNumber,
      DescriptionA,
      DescriptionB,
      ValueA,
      ValueB
      );
  }

  return (ValueA == ValueB);
}

/**
  If the contents of BufferA are identical to the contents of BufferB, then TRUE
  is returned.  If the contents of BufferA are not identical to the contents of
  BufferB, then an assert is triggered and the location of the assert provided
  by FunctionName, LineNumber, FileName, DescriptionA, and DescriptionB are
  recorded and FALSE is returned.

  @param[in]  BufferA       Pointer to a buffer for comparison.
  @param[in]  BufferB       Pointer to a buffer for comparison.
  @param[in]  Length        Number of bytes to compare in BufferA and BufferB.
  @param[in]  FunctionName  Null-terminated ASCII string of the function
                            executing the assert macro.
  @param[in]  LineNumber    The source file line number of the assert macro.
  @param[in]  FileName      Null-terminated ASCII string of the filename
                            executing the assert macro.
  @param[in]  DescriptionA  Null-terminated ASCII string that is a description
                            of BufferA.
  @param[in]  DescriptionB  Null-terminated ASCII string that is a description
                            of BufferB.

  @retval  TRUE   The contents of BufferA are identical to the contents of
                  BufferB.
  @retval  FALSE  The contents of BufferA are not identical to the contents of
                  BufferB.
**/
BOOLEAN
EFIAPI
UnitTestAssertMemEqual (
  IN VOID         *BufferA,
  IN VOID         *BufferB,
  IN UINTN        Length,
  IN CONST CHAR8  *FunctionName,
  IN UINTN        LineNumber,
  IN CONST CHAR8  *FileName,
  IN CONST CHAR8  *DescriptionA,
  IN CONST CHAR8  *DescriptionB
  )
{
  if (CompareMem (BufferA, BufferB, Length) != 0) {
    UT_LOG_ERROR (
      "[ASSERT FAIL] %a:%d: Value %a != %a for length %d bytes!\n",
      FileName,
      LineNumber,
      DescriptionA,
      DescriptionB,
      Length
      );
    UnitTestLogFailure (
      FAILURETYPE_ASSERTEQUAL,
      "%a:%d: Memory at %a != %a for length %d bytes!\n",
      FileName,
      LineNumber,
      DescriptionA,
      DescriptionB,
      Length
      );
    return FALSE;
  }

  return TRUE;
}

/**
  If ValueA is not equal ValueB, then TRUE is returned.
  If ValueA is equal to ValueB, then an assert is triggered and the location
  of the assert provided by FunctionName, LineNumber, FileName, DescriptionA
  and DescriptionB are recorded and FALSE is returned.

  @param[in]  ValueA        64-bit value.
  @param[in]  ValueB        64-bit value.
  @param[in]  FunctionName  Null-terminated ASCII string of the function
                            executing the assert macro.
  @param[in]  LineNumber    The source file line number of the assert macro.
  @param[in]  FileName      Null-terminated ASCII string of the filename
                            executing the assert macro.
  @param[in]  DescriptionA  Null-terminated ASCII string that is a description
                            of ValueA.
  @param[in]  DescriptionB  Null-terminated ASCII string that is a description
                            of ValueB.

  @retval  TRUE   ValueA is not equal to ValueB.
  @retval  FALSE  ValueA is equal to ValueB.
**/
BOOLEAN
EFIAPI
UnitTestAssertNotEqual (
  IN UINT64       ValueA,
  IN UINT64       ValueB,
  IN CONST CHAR8  *FunctionName,
  IN UINTN        LineNumber,
  IN CONST CHAR8  *FileName,
  IN CONST CHAR8  *DescriptionA,
  IN CONST CHAR8  *DescriptionB
  )
{
  if (ValueA == ValueB) {
    UT_LOG_ERROR (
      "[ASSERT FAIL] %a:%d: Value %a == %a (%d == %d)!\n",
      FileName,
      LineNumber,
      DescriptionA,
      DescriptionB,
      ValueA,
      ValueB
      );
    UnitTestLogFailure (
      FAILURETYPE_ASSERTNOTEQUAL,
      "%a:%d: Value %a == %a (%d == %d)!\n",
      FileName,
      LineNumber,
      DescriptionA,
      DescriptionB,
      ValueA,
      ValueB
      );
  }

  return (ValueA != ValueB);
}

/**
  If Status is equal to Expected, then TRUE is returned.
  If Status is not equal to Expected, then an assert is triggered and the
  location of the assert provided by FunctionName, LineNumber, FileName, and
  Description are recorded and FALSE is returned.

  @param[in]  Status        EFI_STATUS value returned from an API under test.
  @param[in]  Expected      The expected EFI_STATUS return value from an API
                            under test.
  @param[in]  FunctionName  Null-terminated ASCII string of the function
                            executing the assert macro.
  @param[in]  LineNumber    The source file line number of the assert macro.
  @param[in]  FileName      Null-terminated ASCII string of the filename
                            executing the assert macro.
  @param[in]  Description   Null-terminated ASCII string that is a description
                            of Status.

  @retval  TRUE   Status is equal to Expected.
  @retval  FALSE  Status is not equal to Expected.
**/
BOOLEAN
EFIAPI
UnitTestAssertStatusEqual (
  IN EFI_STATUS   Status,
  IN EFI_STATUS   Expected,
  IN CONST CHAR8  *FunctionName,
  IN UINTN        LineNumber,
  IN CONST CHAR8  *FileName,
  IN CONST CHAR8  *Description
  )
{
  if (Status != Expected) {
    UT_LOG_ERROR (
      "[ASSERT FAIL] %a:%d: Status '%a' is %r, should be %r!\n",
      FileName,
      LineNumber,
      Description,
      Status,
      Expected
      );
    UnitTestLogFailure (
      FAILURETYPE_ASSERTSTATUSEQUAL,
      "%a:%d: Status '%a' is %r, should be %r!\n",
      FileName,
      LineNumber,
      Description,
      Status,
      Expected
      );
  }

  return (Status == Expected);
}

/**
  If Pointer is not equal to NULL, then TRUE is returned.
  If Pointer is equal to NULL, then an assert is triggered and the location of
  the assert provided by FunctionName, LineNumber, FileName, and PointerName
  are recorded and FALSE is returned.

  @param[in]  Pointer       Pointer value to be checked against NULL.
  @param[in]  Expected      The expected EFI_STATUS return value from a function
                            under test.
  @param[in]  FunctionName  Null-terminated ASCII string of the function
                            executing the assert macro.
  @param[in]  LineNumber    The source file line number of the assert macro.
  @param[in]  FileName      Null-terminated ASCII string of the filename
                            executing the assert macro.
  @param[in]  PointerName   Null-terminated ASCII string that is a description
                            of Pointer.

  @retval  TRUE   Pointer is not equal to NULL.
  @retval  FALSE  Pointer is equal to NULL.
**/
BOOLEAN
EFIAPI
UnitTestAssertNotNull (
  IN VOID         *Pointer,
  IN CONST CHAR8  *FunctionName,
  IN UINTN        LineNumber,
  IN CONST CHAR8  *FileName,
  IN CONST CHAR8  *PointerName
  )
{
  if (Pointer == NULL) {
    UT_LOG_ERROR (
      "[ASSERT FAIL] %a:%d: Pointer (%a) is NULL!\n",
      FileName,
      LineNumber,
      PointerName
      );
    UnitTestLogFailure (
      FAILURETYPE_ASSERTNOTNULL,
      "%a:%d: Pointer (%a) is NULL!\n",
      FileName,
      LineNumber,
      PointerName
      );
  }

  return (Pointer != NULL);
}

/**
  If UnitTestStatus is UNIT_TEST_PASSED, then log an info message and return
  TRUE because an ASSERT() was expected when FunctionCall was executed and an
  ASSERT() was triggered. If UnitTestStatus is UNIT_TEST_SKIPPED, then log a
  warning message and return TRUE because ASSERT() macros are disabled.  If
  UnitTestStatus is UNIT_TEST_ERROR_TEST_FAILED, then log an error message and
  return FALSE because an ASSERT() was expected when FunctionCall was executed,
  but no ASSERT() conditions were triggered.  The log messages contain
  FunctionName, LineNumber, and FileName strings to provide the location of the
  UT_EXPECT_ASSERT_FAILURE() macro.

  @param[in]  UnitTestStatus  The status from UT_EXPECT_ASSERT_FAILURE() that
                              is either pass, skipped, or failed.
  @param[in]  FunctionName    Null-terminated ASCII string of the function
                              executing the UT_EXPECT_ASSERT_FAILURE() macro.
  @param[in]  LineNumber      The source file line number of the the function
                              executing the UT_EXPECT_ASSERT_FAILURE() macro.
  @param[in]  FileName        Null-terminated ASCII string of the filename
                              executing the UT_EXPECT_ASSERT_FAILURE() macro.
  @param[in]  FunctionCall    Null-terminated ASCII string of the function call
                              executed by the UT_EXPECT_ASSERT_FAILURE() macro.
  @param[out] ResultStatus    Used to return the UnitTestStatus value to the
                              caller of UT_EXPECT_ASSERT_FAILURE().  This is
                              optional parameter that may be NULL.

  @retval  TRUE   UnitTestStatus is UNIT_TEST_PASSED.
  @retval  TRUE   UnitTestStatus is UNIT_TEST_SKIPPED.
  @retval  FALSE  UnitTestStatus is UNIT_TEST_ERROR_TEST_FAILED.
**/
BOOLEAN
EFIAPI
UnitTestExpectAssertFailure (
  IN  UNIT_TEST_STATUS  UnitTestStatus,
  IN  CONST CHAR8       *FunctionName,
  IN  UINTN             LineNumber,
  IN  CONST CHAR8       *FileName,
  IN  CONST CHAR8       *FunctionCall,
  OUT UNIT_TEST_STATUS  *ResultStatus  OPTIONAL
  )
{
  if (ResultStatus != NULL) {
    *ResultStatus = UnitTestStatus;
  }

  if (UnitTestStatus == UNIT_TEST_PASSED) {
    UT_LOG_INFO (
      "[ASSERT PASS] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) detected expected assert\n",
      FileName,
      LineNumber,
      FunctionCall
      );
  }

  if (UnitTestStatus == UNIT_TEST_SKIPPED) {
    UT_LOG_WARNING (
      "[ASSERT WARN] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) disabled\n",
      FileName,
      LineNumber,
      FunctionCall
      );
  }

  if (UnitTestStatus == UNIT_TEST_ERROR_TEST_FAILED) {
    UT_LOG_ERROR (
      "[ASSERT FAIL] %a:%d: Function call (%a) did not ASSERT()!\n",
      FileName,
      LineNumber,
      FunctionCall
      );
    UnitTestLogFailure (
      FAILURETYPE_EXPECTASSERT,
      "%a:%d: Function call (%a) did not ASSERT()!\n",
      FileName,
      LineNumber,
      FunctionCall
      );
  }

  return (UnitTestStatus != UNIT_TEST_ERROR_TEST_FAILED);
}
