// Copyright © 2023 Kim Altintop <kim@eagain.io>
// SPDX-License-Identifier: GPL-2.0-only

use autosurgeon::{
    reconcile::NoKey,
    Hydrate,
    HydrateError,
    Reconcile,
    Reconciler,
};
use chrono::{
    DateTime,
    NaiveDateTime,
    Utc,
};

#[derive(Clone, Copy, Debug)]
pub struct Timestamp {
    inner: DateTime<Utc>,
}

impl Timestamp {
    pub fn now() -> Self {
        Self { inner: Utc::now() }
    }
}

impl Hydrate for Timestamp {
    fn hydrate_timestamp(t: i64) -> Result<Self, HydrateError> {
        NaiveDateTime::from_timestamp_millis(t).map_or_else(
            || {
                Err(HydrateError::unexpected(
                    "invalid timestamp",
                    format!("too large integer: {t}"),
                ))
            },
            |ndt| {
                Ok(Timestamp {
                    inner: DateTime::from_naive_utc_and_offset(ndt, Utc),
                })
            },
        )
    }
}

impl Reconcile for Timestamp {
    type Key<'a> = NoKey;

    fn reconcile<R: Reconciler>(&self, mut reconciler: R) -> Result<(), R::Error> {
        reconciler.timestamp(self.inner.timestamp_millis())
    }
}