// Copyright 2016 The Fuchsia Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// A Cobalt day-index assigns to each date of the calendar on or after
// Junuary 1, 1970 a non-negative integer index with
// January 1, 1970 being assigned the index 0. For example
//
// Calendar Date            Cobalt day-index
// ----------              ----------------
// January 1, 1970          0
// January 2, 1970          1
// February 1, 1970         31
// October 18, 2016         17,092
//
// Notice that a day-index does not represent a fixed 24-hour period of real
// time because the day with day-index n has a different meaning in
// different time-zones. Thus there is no well-defined mapping from an
// instant of time to a day index.
//
// For the purpose of aggregating observations for analysis and reporting,
// Cobalt uses three types of epochs: Day, Week, and Month. A week epoch
// is a squence of 7 days from a Sunday to a Saturday. A month epoch is a
// sequence of days in a calendar month.
//
// Each week and month epoch containing days on or after January 1, 1970 is
// also given a zero-based index as follows:
//
// Calendar Week                   Cobalt week epoch index
// ----------------------------    -----------------------
// Thu 1970-1-1  - Sat 1970-1-3     0
// Sun 1970-1-4  - Sat 1970-1-10    1
// Sun 1970-1-11 - Sun 1970-1-17    2
// Sun 1970-1-18 - Sun 1970-1-24    3
// etc.
//
//
// Calendar Month     Cobalt month epoch index
// --------------     -----------------------
// January, 1970      0
// February, 1970     1
// March, 1970        2
// etc.

#ifndef COBALT_UTIL_DATETIME_UTIL_H_
#define COBALT_UTIL_DATETIME_UTIL_H_

#include <atomic>
#include <chrono>
#include <cstdint>

#include "config/metrics.pb.h"

namespace cobalt {
namespace util {

// Unix seconds differ from physical seconds on a day in which there is
// a leap second.
static const uint32_t kNumUnixSecondsPerDay = 60L * 60L * 24L;

static const uint32_t kInvalidIndex = UINT32_MAX;

// A CalendarDate represents a day on the calendar using normal human-readable
// indexing. Just as with day-index there is no well-defined mapping from an
// instant of time to a CalendarDate because this depends on the timezone.
struct CalendarDate {
  // A number from 1 to 31.
  uint32_t day_of_month = 1;

  // 1 = January, 2 = February, ..., 12 = December
  uint32_t month = 1;

  // Calendar year e.g. 2016.
  uint32_t year = 1970;

  bool operator==(const CalendarDate& other) const {
    return (other.day_of_month == day_of_month && other.month == month &&
            other.year == year);
  }
};

// Returns the day index corresponding to |time| in the given |time_zone|
// or UINT32_MAX if |time_zone| is not valid. |time| must be a Unix timestamp,
// that is a number of Unix seconds since the Unix epoch.
uint32_t TimeToDayIndex(time_t time, Metric::TimeZonePolicy time_zone);

// Converts the given CalendarDate to a Cobalt Day Index. If the fields of
// calendar_date do not make sense as a real day of the calendar
// (for example if month=13) then the result is undefined. If the
// specified date is prior to January 1, 1970 or not before the year 10,000
// then the result is undefined.
uint32_t CalendarDateToDayIndex(const CalendarDate& calendar_date);

// Converts the given day_index to a CalendarDate, necessarily on or
// after January 1, 1970.
CalendarDate DayIndexToCalendarDate(uint32_t day_index);

// Given a day_index returns the index of the Cobalt week epoch
// containing that date.
uint32_t DayIndexToWeekIndex(uint32_t day_index);

// Given a CalendarDate returns the index of the Cobalt week epoch
// containing that date. If the fields of calendar_date do not make sense as a
// real day of the calendar (for example if month=13) then the result is
// undefined. If the specified date is prior to January 1, 1970 then the result
// is undefined.
uint32_t CalendarDateToWeekIndex(const CalendarDate& calendar_date);

// Given the index of a Cobalt week epoch returns the CalendarDate for the first
// day of that week epoch. In all cases except week_index=0 the
// returned date will be a Sunday. If week_index=0 the returned date will
// be day zero: Thu 1970-1-1.
CalendarDate WeekIndexToCalendarDate(uint32_t week_index);

// Given a day_index returns the index of the Cobalt month epoch
// containing that date.
uint32_t DayIndexToMonthIndex(uint32_t day_index);

// Given a CalendarDate returns the index of the Cobalt month epoch
// containing that date. If the fields of
// calendar_date do not make sense as a real day of the calendar (for example if
// month=13) then the result is undefined. If the specified date is prior to
// January 1, 1970 then the result is undefined.
uint32_t CalendarDateToMonthIndex(const CalendarDate& calendar_date);

// Given the index of a Cobalt month epoch returns the CalendarDate for the
// first day of that month epoch.
CalendarDate MonthIndexToCalendarDate(uint32_t month_index);

// An abstract clock interface.
class ClockInterface {
 public:
  virtual int64_t CurrentTimeSeconds() = 0;
};

// An implementation of ClockInterface that uses the system clock.
class SystemClock : public ClockInterface {
 public:
  int64_t CurrentTimeSeconds() override {
    return std::chrono::duration_cast<std::chrono::seconds>(
               std::chrono::system_clock::now().time_since_epoch())
        .count();
  }
};

// An implementation of ClockInterface that returns a fixed, settable value.
class StationaryClock : public ClockInterface {
 public:
  StationaryClock() { current_time_seconds_ = 0; }

  int64_t CurrentTimeSeconds() override { return current_time_seconds_; }

  void set_current_time_seconds(int64_t current_time_seconds) {
    current_time_seconds_ = current_time_seconds;
  }

 private:
  std::atomic<int64_t> current_time_seconds_;
};

}  // namespace util
}  // namespace cobalt

#endif  // COBALT_UTIL_DATETIME_UTIL_H_
