/**
  @file
  Display the handles in the system

  Copyright (c) 2011-2012, Intel Corporation
  All rights reserved. This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include <WebServer.h>


/**
  Respond with the handles in the system

  @param [in] SocketFD      The socket's file descriptor to add to the list.
  @param [in] pPort         The WSDT_PORT structure address
  @param [out] pbDone       Address to receive the request completion status

  @retval EFI_SUCCESS       The request was successfully processed

**/
EFI_STATUS
HandlePage (
  IN int SocketFD,
  IN WSDT_PORT * pPort,
  OUT BOOLEAN * pbDone
  )
{
  INTN Digit;
  INTN Entries;
  INTN Index;
  UINTN GuidCount;
  UINTN LengthInBytes;
  UINT8 * pDigit;
  EFI_HANDLE * pHandleArray;
  EFI_HANDLE * pHandle;
  EFI_HANDLE * pHandleEnd;
  EFI_GUID ** ppGuidArray;
  EFI_GUID ** ppGuid;
  EFI_GUID ** ppGuidEnd;
  INTN Shift;
  EFI_STATUS Status;
  UINTN Value;
  CONST UINTN cDigit [] = {
    3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15 };
  
  DBG_ENTER ( );
  
  //
  //  Send the handles page
  //
  for ( ; ; ) {
    //
    //  Send the page header
    //
    Status = HttpPageHeader ( SocketFD, pPort, L"Handle Database" );
    if ( EFI_ERROR ( Status )) {
      break;
    }

    //
    //  Build the table header
    //
    Status = HttpSendAnsiString ( SocketFD,
                                  pPort,
                                  "<h1>Handle Database</h1>\r\n"
                                  "<table border=\"1\">\r\n"
                                  "  <tr bgcolor=\"c0c0ff\"><th>Handle</th><th>Protocol Guids</th></tr>\r\n" );
    if ( EFI_ERROR ( Status )) {
      break;
    }

    //
    //  Determine the number of handles in the database
    //
    LengthInBytes = 0;
    Status = gBS->LocateHandle ( AllHandles,
                                 NULL,
                                 NULL,
                                 &LengthInBytes,
                                 NULL );
    if ( EFI_BUFFER_TOO_SMALL == Status ) {
      //
      //  Allocate space for the handles
      //
      Status = gBS->AllocatePool ( EfiRuntimeServicesData,
                                   LengthInBytes,
                                   (VOID **) &pHandleArray );
      if ( !EFI_ERROR ( Status )) {
        //
        //  Get the list of handles
        //
        Status = gBS->LocateHandle ( AllHandles,
                                     NULL,
                                     NULL,
                                     &LengthInBytes,
                                     pHandleArray );
        if ( !EFI_ERROR ( Status )) {
          Entries = LengthInBytes / sizeof ( *pHandleArray );
          pHandle = pHandleArray;
          pHandleEnd = &pHandle [ Entries ];
          while ( pHandleEnd > pHandle ) {
            //
            //  Build the table entry for this page
            //
            Status = HttpSendAnsiString ( SocketFD,
                                          pPort,
                                          "<tr><td><code>0x" );
            if ( EFI_ERROR ( Status )) {
              break;
            }
            Value = (UINTN) *pHandle;
            for ( Shift = ( sizeof ( Shift ) << 3 ) - 4; 0 <= Shift; Shift -= 4 ) {
              //
              //  Convert the next address nibble to ANSI hex
              //
              Digit = (( Value >> Shift ) & 0xf ) | '0';
              if ( '9' < Digit ) {
                Digit += 'a' - '0' - 10;
              }

              //
              //  Display the address digit
              //
              Status = HttpSendByte ( SocketFD,
                                      pPort,
                                      (UINT8) Digit );
              if ( EFI_ERROR ( Status )) {
                break;
              }
            }
            if ( EFI_ERROR ( Status )) {
              break;
            }

            //
            //  Start the second column
            //
            Status = HttpSendAnsiString ( SocketFD,
                                          pPort,
                                          "</code></td><td><code>\r\n" );
            if ( EFI_ERROR ( Status )) {
              break;
            }

            //
            //  Determine the number of protocols connected to this handle
            //
            Status = gBS->ProtocolsPerHandle ( *pHandle,
                                               &ppGuidArray,
                                               &GuidCount );
            if ( EFI_ERROR ( Status )) {
              break;
            }
            ppGuid = ppGuidArray;
            ppGuidEnd = &ppGuid [ GuidCount ];
            while ( ppGuidEnd > ppGuid ) {
              //
              //  Display the guid
              //
              pDigit = (UINT8 *) *ppGuid;
              for ( Index = 0; 16 > Index; Index++ ) {
                //
                //  Separate the portions of the GUID
                //  99E87DCF-6162-40c5-9FA1-32111F5197F7
                //
                if (( 4 == Index )
                  || ( 6 == Index )
                  || ( 8 == Index )
                  || ( 10 == Index )) {
                  Status = HttpSendByte ( SocketFD,
                                          pPort,
                                          '-' );
                  if ( EFI_ERROR ( Status )) {
                    break;
                  }
                }

                //
                //  Display the GUID digits
                //
                Value = pDigit [ cDigit [ Index ]];
                for ( Shift = 4; 0 <= Shift; Shift -= 4 ) {
                  //
                  //  Convert the next address nibble to ANSI hex
                  //
                  Digit = (( Value >> Shift ) & 0xf ) | '0';
                  if ( '9' < Digit ) {
                    Digit += 'a' - '0' - 10;
                  }
                
                  //
                  //  Display the address digit
                  //
                  Status = HttpSendByte ( SocketFD,
                                          pPort,
                                          (UINT8) Digit );
                  if ( EFI_ERROR ( Status )) {
                    break;
                  }
                }
                if ( EFI_ERROR ( Status )) {
                  break;
                }
              }

              //
              //  Separate each GUID
              //
              Status = HttpSendAnsiString ( SocketFD,
                                            pPort,
                                            "<br/>\r\n" );
              if ( EFI_ERROR ( Status )) {
                break;
              }

              //
              //  Set the next protocol
              //
              ppGuid+= 1;
            }

            //
            //  Free the GUID array
            //
            gBS->FreePool ( ppGuidArray );
            if ( EFI_ERROR ( Status )) {
              break;
            }

            //
            //  End the row
            //
            Status = HttpSendAnsiString ( SocketFD,
                                          pPort,
                                          "</code></td></tr>\r\n" );
            if ( EFI_ERROR ( Status )) {
              break;
            }

            //
            //  Set the next handle
            //
            pHandle += 1;
          }
        }

        //
        //  Done with the handle array
        //
        gBS->FreePool ( pHandleArray );
      }
    }
    
    //
    //  Build the table trailer
    //
    Status = HttpSendAnsiString ( SocketFD,
                                  pPort,
                                  "</table>\r\n" );
    if ( EFI_ERROR ( Status )) {
      break;
    }

    //
    //  Send the page trailer
    //
    Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
    break;
  }
    
  //
  //  Return the operation status
  //
  DBG_EXIT_STATUS ( Status );
  return Status;
}
