// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "quiche_platform_impl/quiche_time_utils_impl.h"

#include "openssl/time.h"

namespace quiche {

// Chrome converts broken out UTC times for certificates to unix times using
// the BoringSSL routines.
std::optional<int64_t> QuicheUtcDateTimeToUnixSecondsImpl(int year, int month,
                                                          int day, int hour,
                                                          int minute,
                                                          int second) {
  struct tm tmp_tm;
  tmp_tm.tm_year = year - 1900;
  tmp_tm.tm_mon = month - 1;
  tmp_tm.tm_mday = day;
  tmp_tm.tm_hour = hour;
  tmp_tm.tm_min = minute;
  tmp_tm.tm_sec = second;
  // BoringSSL POSIX time, like POSIX itself, does not support leap seconds.
  bool leap_second = false;
  if (tmp_tm.tm_sec == 60) {
    tmp_tm.tm_sec = 59;
    leap_second = true;
  }
  int64_t result;
  if (!OPENSSL_tm_to_posix(&tmp_tm, &result)) {
    return std::nullopt;
  }
  // Our desired behaviour is to return the following second for a leap second
  // assuming it is a valid time.
  if (leap_second) {
    if (!OPENSSL_posix_to_tm(result + 1, &tmp_tm)) {
      return std::nullopt;
    }
    result++;
  }
  return result;
}

}  // namespace quiche
