/** @file
*
*  Copyright (c) 2016, Hisilicon Limited. All rights reserved.
*  Copyright (c) 2016-2019, Linaro Limited. All rights reserved.
*  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.
*
*  SPDX-License-Identifier: BSD-2-Clause-Patent
*
**/

#include <Uefi/UefiBaseType.h>
#include <Uefi/UefiSpec.h>
#include <Library/DebugLib.h>
#include <Library/TimeBaseLib.h>

/**
  Converts Epoch seconds (elapsed since 1970 JANUARY 01, 00:00:00 UTC) to EFI_TIME.

  @param  EpochSeconds   Epoch seconds.
  @param  Time           The time converted to UEFI format.

**/
VOID
EFIAPI
EpochToEfiTime (
  IN  UINTN     EpochSeconds,
  OUT EFI_TIME  *Time
  )
{
  UINTN         a;
  UINTN         b;
  UINTN         c;
  UINTN         d;
  UINTN         g;
  UINTN         j;
  UINTN         m;
  UINTN         y;
  UINTN         da;
  UINTN         db;
  UINTN         dc;
  UINTN         dg;
  UINTN         hh;
  UINTN         mm;
  UINTN         ss;
  UINTN         J;

  J  = (EpochSeconds / 86400) + 2440588;
  j  = J + 32044;
  g  = j / 146097;
  dg = j % 146097;
  c  = (((dg / 36524) + 1) * 3) / 4;
  dc = dg - (c * 36524);
  b  = dc / 1461;
  db = dc % 1461;
  a  = (((db / 365) + 1) * 3) / 4;
  da = db - (a * 365);
  y  = (g * 400) + (c * 100) + (b * 4) + a;
  m  = (((da * 5) + 308) / 153) - 2;
  d  = da - (((m + 4) * 153) / 5) + 122;

  Time->Year  = (UINT16)(y - 4800 + ((m + 2) / 12));
  Time->Month = ((m + 2) % 12) + 1;
  Time->Day   = (UINT8)(d + 1);

  ss = EpochSeconds % 60;
  a  = (EpochSeconds - ss) / 60;
  mm = a % 60;
  b = (a - mm) / 60;
  hh = b % 24;

  Time->Hour        = (UINT8)hh;
  Time->Minute      = (UINT8)mm;
  Time->Second      = (UINT8)ss;
  Time->Nanosecond  = 0;

}

/**
  Calculate Epoch days.

  @param    Time  The UEFI time to be calculated.

  @return   Number of days.

**/
UINTN
EFIAPI
EfiGetEpochDays (
  IN  EFI_TIME  *Time
  )
{
  UINTN a;
  UINTN y;
  UINTN m;
  UINTN JulianDate;  // Absolute Julian Date representation of the supplied Time
  UINTN EpochDays;   // Number of days elapsed since EPOCH_JULIAN_DAY

  a = (14 - Time->Month) / 12 ;
  y = Time->Year + 4800 - a;
  m = Time->Month + (12*a) - 3;

  JulianDate = Time->Day + ((153*m + 2)/5) + (365*y) + (y/4) - (y/100) + (y/400) - 32045;

  ASSERT (JulianDate >= EPOCH_JULIAN_DATE);
  EpochDays = JulianDate - EPOCH_JULIAN_DATE;

  return EpochDays;
}

/**
  Converts EFI_TIME to Epoch seconds (elapsed since 1970 JANUARY 01, 00:00:00 UTC).

  @param    Time  The UEFI time to be converted.

  @return   Number of seconds.

**/
UINTN
EFIAPI
EfiTimeToEpoch (
  IN  EFI_TIME  *Time
  )
{
  UINTN EpochDays;   // Number of days elapsed since EPOCH_JULIAN_DAY
  UINTN EpochSeconds;

  EpochDays = EfiGetEpochDays (Time);

  EpochSeconds = (EpochDays * SEC_PER_DAY) + ((UINTN)Time->Hour * SEC_PER_HOUR) + (Time->Minute * SEC_PER_MIN) + Time->Second;

  return EpochSeconds;
}

/**
  Get the day of the week from the UEFI time.

  @param    Time  The UEFI time to be calculated.

  @return   The day of the week: Sunday=0, Monday=1, ... Saturday=6

**/
UINTN
EfiTimeToWday (
  IN  EFI_TIME  *Time
  )
{
  UINTN EpochDays;   // Number of days elapsed since EPOCH_JULIAN_DAY

  EpochDays = EfiGetEpochDays (Time);

  // 4=1/1/1970 was a Thursday

  return (EpochDays + 4) % 7;
}

/**
  Check if it is a leap year.

  @param    Time  The UEFI time to be checked.

  @retval   TRUE  It is a leap year.
  @retval   FALSE It is NOT a leap year.

**/
BOOLEAN
EFIAPI
IsLeapYear (
  IN EFI_TIME   *Time
  )
{
  if (Time->Year % 4 == 0) {
    if (Time->Year % 100 == 0) {
      if (Time->Year % 400 == 0) {
        return TRUE;
      } else {
        return FALSE;
      }
    } else {
      return TRUE;
    }
  } else {
    return FALSE;
  }
}

/**
  Check if the day in the UEFI time is valid.

  @param    Time    The UEFI time to be checked.

  @retval   TRUE    Valid.
  @retval   FALSE   Invalid.

**/
BOOLEAN
EFIAPI
IsDayValid (
  IN  EFI_TIME  *Time
  )
{
  STATIC CONST INTN DayOfMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

  if (Time->Day < 1 ||
      Time->Day > DayOfMonth[Time->Month - 1] ||
      (Time->Month == 2 && (!IsLeapYear (Time) && Time->Day > 28))
     ) {
    return FALSE;
  }

  return TRUE;
}

/**
  Check if the time zone is valid.
  Valid values are between -1440 and 1440 or 2047 (EFI_UNSPECIFIED_TIMEZONE).

  @param    TimeZone    The time zone to be checked.

  @retval   TRUE    Valid.
  @retval   FALSE   Invalid.

**/
BOOLEAN
EFIAPI
IsValidTimeZone (
  IN  INT16  TimeZone
  )
{
  return TimeZone == EFI_UNSPECIFIED_TIMEZONE ||
         (TimeZone >= -1440 && TimeZone <= 1440);
}

/**
  Check if the daylight is valid.
  Valid values are:
    0 : Time is not affected.
    1 : Time is affected, and has not been adjusted for daylight savings.
    3 : Time is affected, and has been adjusted for daylight savings.
  All other values are invalid.

  @param    Daylight    The daylight to be checked.

  @retval   TRUE    Valid.
  @retval   FALSE   Invalid.

**/
BOOLEAN
EFIAPI
IsValidDaylight (
  IN  INT8  Daylight
  )
{
  return Daylight == 0 ||
         Daylight == EFI_TIME_ADJUST_DAYLIGHT ||
         Daylight == (EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT);
}

/**
  Check if the UEFI time is valid.

  @param    Time    The UEFI time to be checked.

  @retval   TRUE    Valid.
  @retval   FALSE   Invalid.

**/
BOOLEAN
EFIAPI
IsTimeValid (
  IN EFI_TIME *Time
  )
{
  // Check the input parameters are within the range specified by UEFI
  if ((Time->Year  < 2000)              ||
     (Time->Year   > 2099)              ||
     (Time->Month  < 1   )              ||
     (Time->Month  > 12  )              ||
     (!IsDayValid (Time) )              ||
     (Time->Hour   > 23  )              ||
     (Time->Minute > 59  )              ||
     (Time->Second > 59  )              ||
     (Time->Nanosecond > 999999999)     ||
     (!IsValidTimeZone(Time->TimeZone)) ||
     (!IsValidDaylight(Time->Daylight))) {
    return FALSE;
  }

  return TRUE;
}
