/** @file
  Provides services to display completion progress of a firmware update on a
  graphical console that supports the Graphics Output Protocol.

  Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
  Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <PiDxe.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseLib.h>
#include <Library/UefiLib.h>

#include <Protocol/GraphicsOutput.h>
#include <Protocol/BootLogo2.h>

//
// Values in percent of of logo height.
//
#define LOGO_BOTTOM_PADDING    20
#define PROGRESS_BLOCK_HEIGHT  10

//
// Graphics Output Protocol instance to display progress bar
//
EFI_GRAPHICS_OUTPUT_PROTOCOL  *mGop = NULL;

//
// Set to 100 percent so it is reset on first call.
//
UINTN  mPreviousProgress = 100;

//
// Display coordinates for the progress bar.
//
UINTN  mStartX = 0;
UINTN  mStartY = 0;

//
// Width and height of the progress bar.
//
UINTN  mBlockWidth  = 0;
UINTN  mBlockHeight = 0;

//
// GOP bitmap of the progress bar. Initialized on every new progress of 100%
//
EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *mBlockBitmap;

//
// GOP bitmap of the progress bar backround.  Initialized once.
//
EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *mProgressBarBackground;

//
// Default mask used to detect the left, right , top, and bottom of logo.  Only
// green and blue pixels are used for logo detection.
//
const EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION  mLogoDetectionColorMask = {
  {
    0xFF,  // Blue
    0xFF,  // Green
    0x00,  // Red
    0x00   // Reserved
  }
};

//
// Background color of progress bar.  Grey.
//
const EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION  mProgressBarBackgroundColor = {
  {
    0x80,  // Blue
    0x80,  // Green
    0x80,  // Red
    0x00   // Reserved
  }
};

//
// Default color of progress completion.  White.
//
const EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION  mProgressBarDefaultColor = {
  {
    0xFF,  // Blue
    0xFF,  // Green
    0xFF,  // Red
    0x00   // Reserved
  }
};

//
// Set to TRUE if a valid Graphics Output Protocol is found and the progress
// bar fits under the boot logo using the current graphics mode.
//
BOOLEAN  mGraphicsGood = FALSE;

/**
  Internal function used to find the bounds of the white logo (on black or
  red background).

  These bounds are then computed to find the block size, 0%, 100%, etc.

**/
VOID
FindDim (
  VOID
  )
{
  EFI_STATUS                           Status;
  INTN                                 LogoX;
  INTN                                 LogoStartX;
  INTN                                 LogoEndX;
  INTN                                 LogoY;
  INTN                                 LogoStartY;
  INTN                                 LogoEndY;
  UINTN                                OffsetX;     // Logo screen coordinate
  UINTN                                OffsetY;     // Logo screen coordinate
  UINTN                                Width;       // Width of logo in pixels
  UINTN                                Height;      // Height of logo in pixels
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL        *Logo;
  EDKII_BOOT_LOGO2_PROTOCOL            *BootLogo;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION  *Pixel;

  Logo     = NULL;
  BootLogo = NULL;

  //
  // Return if a Graphics Output Protocol ha snot been found.
  //
  if (mGop == NULL) {
    DEBUG ((DEBUG_ERROR, "No GOP found.  No progress bar support. \n"));
    return;
  }

  //
  // Get boot logo protocol so we know where on the screen to grab
  //
  Status = gBS->LocateProtocol (
                  &gEdkiiBootLogo2ProtocolGuid,
                  NULL,
                  (VOID **)&BootLogo
                  );
  if ((BootLogo == NULL) || (EFI_ERROR (Status))) {
    DEBUG ((DEBUG_ERROR, "Failed to locate gEdkiiBootLogo2ProtocolGuid Status = %r.  No Progress bar support. \n", Status));
    return;
  }

  //
  // Get logo location and size
  //
  Status = BootLogo->GetBootLogo (
                       BootLogo,
                       &Logo,
                       &OffsetX,
                       &OffsetY,
                       &Width,
                       &Height
                       );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Failed to Get Boot Logo Status = %r.  No Progress bar support. \n", Status));
    return;
  }

  //
  // Within logo buffer find where the actual logo starts/ends
  //
  LogoEndX = 0;
  LogoEndY = 0;

  //
  // Find left side of logo in logo coordinates
  //
  for (LogoX = 0, LogoStartX = Width; LogoX < LogoStartX; LogoX++) {
    Pixel = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION *)(Logo + LogoX);
    for (LogoY = 0; LogoY < (INTN)Height; LogoY++) {
      if ((Pixel->Raw & mLogoDetectionColorMask.Raw) != 0x0) {
        LogoStartX = LogoX;
        //
        // For loop searches from right side back to this column.
        //
        LogoEndX = LogoX;
        DEBUG ((DEBUG_INFO, "StartX found at (%d, %d) Color is: 0x%X \n", LogoX, LogoY, Pixel->Raw));
        break;
      }

      Pixel = Pixel + Width;
    }
  }

  //
  // Find right side of logo
  //
  for (LogoX = Width - 1; LogoX >= LogoEndX; LogoX--) {
    Pixel = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION *)(Logo + LogoX);
    for (LogoY = 0; LogoY < (INTN)Height; LogoY++) {
      if ((Pixel->Raw & mLogoDetectionColorMask.Raw) != 0x0) {
        LogoEndX = LogoX;
        DEBUG ((DEBUG_INFO, "EndX found at (%d, %d) Color is: 0x%X \n", LogoX, LogoY, Pixel->Raw));
        break;
      }

      Pixel = Pixel + Width;
    }
  }

  //
  // Compute mBlockWidth
  //
  mBlockWidth = ((LogoEndX - LogoStartX) + 99) / 100;

  //
  // Adjust mStartX based on block width so it is centered under logo
  //
  mStartX = LogoStartX + OffsetX - (((mBlockWidth * 100) - (LogoEndX - LogoStartX)) / 2);
  DEBUG ((DEBUG_INFO, "mBlockWidth set to 0x%X\n", mBlockWidth));
  DEBUG ((DEBUG_INFO, "mStartX set to 0x%X\n", mStartX));

  //
  // Find the top of the logo
  //
  for (LogoY = 0, LogoStartY = Height; LogoY < LogoStartY; LogoY++) {
    Pixel = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION *)(Logo + (Width * LogoY));
    for (LogoX = 0; LogoX < (INTN)Width; LogoX++) {
      // not black or red
      if ((Pixel->Raw & mLogoDetectionColorMask.Raw) != 0x0) {
        LogoStartY = LogoY;
        LogoEndY   = LogoY; // for next loop will search from bottom side back to this row.
        DEBUG ((DEBUG_INFO, "StartY found at (%d, %d) Color is: 0x%X \n", LogoX, LogoY, Pixel->Raw));
        break;
      }

      Pixel++;
    }
  }

  //
  // Find the bottom of the logo
  //
  for (LogoY = Height - 1; LogoY >= LogoEndY; LogoY--) {
    Pixel = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION *)(Logo + (Width * LogoY));
    for (LogoX = 0; LogoX < (INTN)Width; LogoX++) {
      if ((Pixel->Raw & mLogoDetectionColorMask.Raw) != 0x0) {
        LogoEndY = LogoY;
        DEBUG ((DEBUG_INFO, "EndY found at (%d, %d) Color is: 0x%X \n", LogoX, LogoY, Pixel->Raw));
        break;
      }

      Pixel++;
    }
  }

  //
  // Compute bottom padding (distance between logo bottom and progress bar)
  //
  mStartY = (((LogoEndY - LogoStartY) * LOGO_BOTTOM_PADDING) / 100) + LogoEndY + OffsetY;

  //
  // Compute progress bar height
  //
  mBlockHeight = (((LogoEndY - LogoStartY) * PROGRESS_BLOCK_HEIGHT) / 100);

  DEBUG ((DEBUG_INFO, "mBlockHeight set to 0x%X\n", mBlockHeight));

  //
  // Create progress bar background (one time init).
  //
  mProgressBarBackground = AllocatePool (mBlockWidth * 100 * mBlockHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
  if (mProgressBarBackground == NULL) {
    DEBUG ((DEBUG_ERROR, "Failed to allocate progress bar background\n"));
    return;
  }

  //
  // Fill the progress bar with the background color
  //
  SetMem32 (
    mProgressBarBackground,
    (mBlockWidth * 100 * mBlockHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)),
    mProgressBarBackgroundColor.Raw
    );

  //
  // Allocate mBlockBitmap
  //
  mBlockBitmap = AllocatePool (mBlockWidth * mBlockHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
  if (mBlockBitmap == NULL) {
    FreePool (mProgressBarBackground);
    DEBUG ((DEBUG_ERROR, "Failed to allocate block\n"));
    return;
  }

  //
  // Check screen width and height and make sure it fits.
  //
  if ((mBlockHeight > Height) || (mBlockWidth > Width) || (mBlockHeight < 1) || (mBlockWidth < 1)) {
    DEBUG ((DEBUG_ERROR, "DisplayUpdateProgressLib - Progress - Failed to get valid width and height.\n"));
    DEBUG ((DEBUG_ERROR, "DisplayUpdateProgressLib - Progress - mBlockHeight: 0x%X  mBlockWidth: 0x%X.\n", mBlockHeight, mBlockWidth));
    FreePool (mProgressBarBackground);
    FreePool (mBlockBitmap);
    return;
  }

  mGraphicsGood = TRUE;
}

/**
  Function indicates the current completion progress of a firmware update.
  Platform may override with its own specific function.

  @param[in] Completion  A value between 0 and 100 indicating the current
                         completion progress of a firmware update.  This
                         value must the the same or higher than previous
                         calls to this service.  The first call of 0 or a
                         value of 0 after reaching a value of 100 resets
                         the progress indicator to 0.
  @param[in] Color       Color of the progress indicator.  Only used when
                         Completion is 0 to set the color of the progress
                         indicator.  If Color is NULL, then the default color
                         is used.

  @retval EFI_SUCCESS            Progress displayed successfully.
  @retval EFI_INVALID_PARAMETER  Completion is not in range 0..100.
  @retval EFI_INVALID_PARAMETER  Completion is less than Completion value from
                                 a previous call to this service.
  @retval EFI_NOT_READY          The device used to indicate progress is not
                                 available.
**/
EFI_STATUS
EFIAPI
DisplayUpdateProgress (
  IN UINTN                                Completion,
  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION  *Color       OPTIONAL
  )
{
  EFI_STATUS  Status;
  UINTN       PreX;
  UINTN       Index;

  //
  // Check range
  //
  if (Completion > 100) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check to see if this Completion percentage has already been displayed
  //
  if (Completion == mPreviousProgress) {
    return EFI_SUCCESS;
  }

  //
  // Find Graphics Output Protocol if not already set.  1 time.
  //
  if (mGop == NULL) {
    Status = gBS->HandleProtocol (
                    gST->ConsoleOutHandle,
                    &gEfiGraphicsOutputProtocolGuid,
                    (VOID **)&mGop
                    );
    if (EFI_ERROR (Status)) {
      Status = gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid, NULL, (VOID **)&mGop);
      if (EFI_ERROR (Status)) {
        mGop = NULL;
        DEBUG ((DEBUG_ERROR, "Show Progress Function could not locate GOP.  Status = %r\n", Status));
        return EFI_NOT_READY;
      }
    }

    //
    // Run once
    //
    FindDim ();
  }

  //
  // Make sure a valid start, end, and size info are available (find the Logo)
  //
  if (!mGraphicsGood) {
    DEBUG ((DEBUG_INFO, "Graphics Not Good.  Not doing any onscreen visual display\n"));
    return EFI_NOT_READY;
  }

  //
  // Do special init on first call of each progress session
  //
  if (mPreviousProgress == 100) {
    //
    // Draw progress bar background
    //
    mGop->Blt (
            mGop,
            mProgressBarBackground,
            EfiBltBufferToVideo,
            0,
            0,
            mStartX,
            mStartY,
            (mBlockWidth * 100),
            mBlockHeight,
            0
            );

    DEBUG ((
      DEBUG_VERBOSE,
      "Color is 0x%X\n",
      (Color == NULL) ? mProgressBarDefaultColor.Raw : Color->Raw
      ));

    //
    // Update block bitmap with correct color
    //
    SetMem32 (
      mBlockBitmap,
      (mBlockWidth * mBlockHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)),
      (Color == NULL) ? mProgressBarDefaultColor.Raw : Color->Raw
      );

    //
    // Clear previous
    //
    mPreviousProgress = 0;
  }

  //
  // Can not update progress bar if Completion is less than previous
  //
  if (Completion < mPreviousProgress) {
    DEBUG ((DEBUG_WARN, "WARNING: Completion (%d) should not be lesss than Previous (%d)!!!\n", Completion, mPreviousProgress));
    return EFI_INVALID_PARAMETER;
  }

  PreX = ((mPreviousProgress * mBlockWidth) + mStartX);
  for (Index = 0; Index < (Completion - mPreviousProgress); Index++) {
    //
    // Show progress by coloring new area
    //
    mGop->Blt (
            mGop,
            mBlockBitmap,
            EfiBltBufferToVideo,
            0,
            0,
            PreX,
            mStartY,
            mBlockWidth,
            mBlockHeight,
            0
            );
    PreX += mBlockWidth;
  }

  mPreviousProgress = Completion;

  return EFI_SUCCESS;
}
