/** @file
  Module for clarifying the content of the smbios structure element info.

  Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved. <BR>
  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 "../UefiShellDebug1CommandsLib.h"
#include "PrintInfo.h"
#include "QueryTable.h"
#include "EventLogInfo.h"

/**
  Function to display system event log access information.

  @param[in] Key    Additional information to print.
  @param[in] Option Whether to print the additional information.
**/
VOID
EFIAPI
DisplaySELAccessMethod (
  IN CONST UINT8 Key,
  IN CONST UINT8 Option
  )
{
  //
  // Print prompt
  //
  ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_ACCESS_METHOD), gShellDebug1HiiHandle);
  PRINT_INFO_OPTION (Key, Option);

  //
  // Print value info
  //
  switch (Key) {
  case 0:
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_ONE_EIGHT_BIT), gShellDebug1HiiHandle);
    break;

  case 1:
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_TWO_EIGHT_BITS), gShellDebug1HiiHandle);
    break;

  case 2:
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_ONE_SIXTEEN_BIT), gShellDebug1HiiHandle);
    break;

  case 3:
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_MEM_MAPPED_PHYS), gShellDebug1HiiHandle);
    break;

  case 4:
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_AVAIL_VIA_GENERAL), gShellDebug1HiiHandle);
    break;

  default:
    if (Key <= 0x7f) {
      ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_AVAIL_FOR_FUTURE_ASSIGN), gShellDebug1HiiHandle);
    } else {
      ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_BIOS_VENDOR_OEM), gShellDebug1HiiHandle);
    }
  }
}

/**
  Function to display system event log status information.

  @param[in] Key    Additional information to print.
  @param[in] Option Whether to print the additional information.
**/
VOID
EFIAPI
DisplaySELLogStatus (
  UINT8 Key,
  UINT8 Option
  )
{
  //
  // Print prompt
  //
  ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_LOG_STATUS), gShellDebug1HiiHandle);
  PRINT_INFO_OPTION (Key, Option);

  //
  // Print value info
  //
  if ((Key & 0x01) != 0) {
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_LOG_AREA_VALID), gShellDebug1HiiHandle);
  } else {
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_LOG_AREA_VALID), gShellDebug1HiiHandle);
  }

  if ((Key & 0x02) != 0) {
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_LOG_AREA_FULL), gShellDebug1HiiHandle);
  } else {
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_LOG_AREA_NOT_FULL), gShellDebug1HiiHandle);
  }

  if ((Key & 0xFC) != 0) {
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_RES_BITS_NOT_ZERO), gShellDebug1HiiHandle, Key & 0xFC);
  }
}

/**
  Function to display system event log header format information.

  @param[in] Key    Additional information to print.
  @param[in] Option Whether to print the additional information.
**/
VOID
EFIAPI
DisplaySysEventLogHeaderFormat (
  UINT8 Key,
  UINT8 Option
  )
{
  //
  // Print prompt
  //
  ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_LOG_HEADER_FORMAT), gShellDebug1HiiHandle);
  PRINT_INFO_OPTION (Key, Option);

  //
  // Print value info
  //
  if (Key == 0x00) {
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_NO_HEADER), gShellDebug1HiiHandle);
  } else if (Key == 0x01) {
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_TYPE_LOG_HEADER), gShellDebug1HiiHandle);
  } else if (Key <= 0x7f) {
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_AVAIL_FOR_FUTURE), gShellDebug1HiiHandle);
  } else {
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_BIOS_VENDOR), gShellDebug1HiiHandle);
  }
}

/**
  Display the header information for SEL log items.

  @param[in] Key      The information key.
  @param[in] Option   The option index.
**/
VOID
DisplaySELLogHeaderLen (
  UINT8 Key,
  UINT8 Option
  )
{
  ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_LOG_HEADER_LEN), gShellDebug1HiiHandle);
  PRINT_INFO_OPTION (Key, Option);

  ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_ONE_VAR_D), gShellDebug1HiiHandle, Key & 0x7F);

  //
  // The most-significant bit of the field specifies
  // whether (0) or not (1) the record has been read
  //
  if ((Key & 0x80) != 0) {
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_THIS_RECORD_READ), gShellDebug1HiiHandle);
  } else {
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_THIS_RECORD_NOT_READ), gShellDebug1HiiHandle);
  }
}

/**
  Display the header information for type 1 items.

  @param[in] LogHeader      The buffer with the information.
**/
VOID
DisplaySysEventLogHeaderType1 (
  IN UINT8 *LogHeader
  )
{
  LOG_HEADER_TYPE1_FORMAT *Header;

  ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_SYSTEM_EVENT_LOG), gShellDebug1HiiHandle);

  //
  // Print Log Header Type1 Format info
  //
  Header = (LOG_HEADER_TYPE1_FORMAT *) (LogHeader);

  ShellPrintHiiEx(-1,-1,NULL,
    STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_OEM_RESERVED),
    gShellDebug1HiiHandle,
    Header->OEMReserved[0],
    Header->OEMReserved[1],
    Header->OEMReserved[2],
    Header->OEMReserved[3],
    Header->OEMReserved[4]
   );
  ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_MULTIPLE_EVENT_TIME), gShellDebug1HiiHandle, Header->Metw);
  ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_MULTIPLE_EVENT_COUNT), gShellDebug1HiiHandle, Header->Meci);
  ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_PREBOOT_ADDRESS), gShellDebug1HiiHandle, Header->CMOSAddress);
  ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_PREBOOT_INDEX), gShellDebug1HiiHandle, Header->CMOSBitIndex);
  ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_CHECKSUM_STARTING_OFF), gShellDebug1HiiHandle, Header->StartingOffset);
  ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_CHECKSUN_BYTE_COUNT), gShellDebug1HiiHandle, Header->ChecksumOffset);
  ShellPrintHiiEx(-1,-1,NULL,
    STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_RESERVED),
    gShellDebug1HiiHandle,
    Header->OEMReserved[0],
    Header->OEMReserved[1],
    Header->OEMReserved[2]
   );
  ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_HEADER_REVISION), gShellDebug1HiiHandle, Header->HeaderRevision);
}

/**
  Function to display system event log header information.

  @param[in] LogHeaderFormat  Format identifier.
  @param[in] LogHeader        Format informcation.
**/
VOID
EFIAPI
DisplaySysEventLogHeader (
  UINT8 LogHeaderFormat,
  UINT8 *LogHeader
  )
{
  //
  // Print prompt
  //
  ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_LOG_HEADER), gShellDebug1HiiHandle);

  //
  // Print value info
  //
  if (LogHeaderFormat == 0x00) {
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_NO_HEADER), gShellDebug1HiiHandle);
  } else if (LogHeaderFormat == 0x01) {
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_TYPE_LOG_HEADER), gShellDebug1HiiHandle);
    DisplaySysEventLogHeaderType1 (LogHeader);
  } else if (LogHeaderFormat <= 0x7f) {
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_AVAIL_FUTURE_ASSIGN), gShellDebug1HiiHandle);
  } else {
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_BIOS_VENDOR), gShellDebug1HiiHandle);
  }
}

/**
  Display the El Vdf information.

  @param[in] ElVdfType    The information type.
  @param[in] VarData      The information buffer.
**/
VOID
DisplayElVdfInfo (
  UINT8 ElVdfType,
  UINT8 *VarData
  )
{
  UINT16  *Word;
  UINT32  *Dword;

  //
  // Display Type Name
  //
  DisplaySELVarDataFormatType (ElVdfType, SHOW_DETAIL);

  //
  // Display Type description
  //
  switch (ElVdfType) {
  case 0:
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_NO_STD_FORMAT), gShellDebug1HiiHandle);
    break;

  case 1:
    Word = (UINT16 *) (VarData + 1);
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_SMBIOS_STRUCT_ASSOC), gShellDebug1HiiHandle);
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_STRUCT_HANDLE), gShellDebug1HiiHandle, *Word);
    break;

  case 2:
    Dword = (UINT32 *) (VarData + 1);
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_MULT_EVENT_COUNTER), gShellDebug1HiiHandle, *Dword);
    break;

  case 3:
    Word = (UINT16 *) (VarData + 1);
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_SMBIOS_STRUCT_ASSOC), gShellDebug1HiiHandle);
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_STRUCT_HANDLE), gShellDebug1HiiHandle, *Word);
    //
    // Followed by a multiple-event counter
    //
    Dword = (UINT32 *) (VarData + 1);
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_MULT_EVENT_COUNTER), gShellDebug1HiiHandle, *Dword);
    break;

  case 4:
    Dword = (UINT32 *) (VarData + 1);
    DisplayPostResultsBitmapDw1 (*Dword, SHOW_DETAIL);
    Dword++;
    DisplayPostResultsBitmapDw2 (*Dword, SHOW_DETAIL);
    break;

  case 5:
    Dword = (UINT32 *) (VarData + 1);
    DisplaySELSysManagementTypes (*Dword, SHOW_DETAIL);
    break;

  case 6:
    Dword = (UINT32 *) (VarData + 1);
    DisplaySELSysManagementTypes (*Dword, SHOW_DETAIL);
    //
    // Followed by a multiple-event counter
    //
    Dword = (UINT32 *) (VarData + 1);
    ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_MULT_EVENT_COUNTER), gShellDebug1HiiHandle, *Dword);
    break;

  default:
    if (ElVdfType <= 0x7F) {
      ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_UNUSED_AVAIL_FOR_ASSIGN), gShellDebug1HiiHandle);
    } else {
      ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_AVAIL_FOR_SYSTEM), gShellDebug1HiiHandle);
    }
  }
}

/**
  Function to display system event log data.

  @param[in] LogData        The data information.
  @param[in] LogAreaLength  Length of the data.
**/
VOID
EFIAPI
DisplaySysEventLogData (
  UINT8   *LogData,
  UINT16  LogAreaLength
  )
{
  LOG_RECORD_FORMAT *Log;
  UINT8             ElVdfType;
  //
  // Event Log Variable Data Format Types
  //
  UINTN             Offset;

  //
  // Print prompt
  //
  ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_SYSTEM_EVENT_LOG_2), gShellDebug1HiiHandle);

  //
  // Print Log info
  //
  Offset  = 0;
  Log     = (LOG_RECORD_FORMAT *) LogData;
  while (Log != NULL && Log->Type != END_OF_LOG && Offset < LogAreaLength) {
    //
    // Get a Event Log Record
    //
    Log = (LOG_RECORD_FORMAT *) (LogData + Offset);

    if (Log != NULL) {
      //
      // Display Event Log Record Information
      //
      DisplaySELVarDataFormatType (Log->Type, SHOW_DETAIL);
      DisplaySELLogHeaderLen (Log->Length, SHOW_DETAIL);

      Offset += Log->Length;
      //
      // Display Log Header Date/Time Fields
      // These fields contain the BCD representation of the date and time
      // (as read from CMOS) of the occurrence of the event
      // So Print as hex and represent decimal
      //
      ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_DATE), gShellDebug1HiiHandle);
      if (Log != NULL && Log->Year >= 80 && Log->Year <= 99) {
        Print (L"19");
      } else if (Log != NULL && Log->Year <= 79) {
        Print (L"20");
      } else {
        ShellPrintHiiEx(-1,-1,NULL,STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_ERROR), gShellDebug1HiiHandle);
        continue;
      }

      ShellPrintHiiEx(-1,-1,NULL,
        STRING_TOKEN (STR_SMBIOSVIEW_EVENTLOGINFO_TIME_SIX_VARS),
        gShellDebug1HiiHandle,
        Log->Year,
        Log->Month,
        Log->Day,
        Log->Hour,
        Log->Minute,
        Log->Second
       );

      //
      // Display Variable Data Format
      //
      if (Log->Length <= (sizeof (LOG_RECORD_FORMAT) - 1)) {
        continue;
      }

      ElVdfType = Log->LogVariableData[0];
      DisplayElVdfInfo (ElVdfType, Log->LogVariableData);
    }
  }
}
