// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.

use chrono::{DateTime, Local, Utc};
use core::fmt;
use serde::{
    Deserialize, Deserializer, Serialize, Serializer,
    de::{self, Visitor},
};
use std::{
    ops::{Add, Sub},
    time::{Duration, SystemTime, UNIX_EPOCH},
};

use crate::IggyDuration;

/// A struct that represents a timestamp.
///
/// This struct uses `SystemTime` from `std::time` crate.
///
/// # Example
///
/// ```
/// use iggy_common::IggyTimestamp;
///
/// let timestamp = IggyTimestamp::from(1694968446131680);
/// assert_eq!(timestamp.to_utc_string("%Y-%m-%d %H:%M:%S"), "2023-09-17 16:34:06");
/// assert_eq!(timestamp.as_micros(), 1694968446131680);
/// ```
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct IggyTimestamp(SystemTime);

pub const UTC_TIME_FORMAT: &str = "%Y-%m-%d %H:%M:%S";

impl IggyTimestamp {
    pub fn now() -> Self {
        IggyTimestamp::default()
    }

    pub fn zero() -> Self {
        IggyTimestamp(UNIX_EPOCH)
    }

    pub fn to_secs(&self) -> u64 {
        self.0.duration_since(UNIX_EPOCH).unwrap().as_secs()
    }

    pub fn as_micros(&self) -> u64 {
        self.0.duration_since(UNIX_EPOCH).unwrap().as_micros() as u64
    }

    pub fn as_millis(&self) -> u64 {
        self.0.duration_since(UNIX_EPOCH).unwrap().as_millis() as u64
    }

    pub fn as_nanos(&self) -> u128 {
        self.0.duration_since(UNIX_EPOCH).unwrap().as_nanos()
    }

    pub fn to_rfc3339_string(&self) -> String {
        DateTime::<Utc>::from(self.0).to_rfc3339()
    }

    pub fn to_utc_string(&self, format: &str) -> String {
        DateTime::<Utc>::from(self.0).format(format).to_string()
    }

    pub fn to_local_string(&self, format: &str) -> String {
        DateTime::<Local>::from(self.0).format(format).to_string()
    }
}

impl From<u64> for IggyTimestamp {
    fn from(timestamp: u64) -> Self {
        IggyTimestamp(UNIX_EPOCH + Duration::from_micros(timestamp))
    }
}

impl From<IggyTimestamp> for u64 {
    fn from(timestamp: IggyTimestamp) -> u64 {
        timestamp.as_micros()
    }
}

impl From<SystemTime> for IggyTimestamp {
    fn from(timestamp: SystemTime) -> Self {
        IggyTimestamp(timestamp)
    }
}

impl Add<SystemTime> for IggyTimestamp {
    type Output = IggyTimestamp;

    fn add(self, other: SystemTime) -> IggyTimestamp {
        IggyTimestamp(self.0 + other.duration_since(UNIX_EPOCH).unwrap())
    }
}

impl Sub<SystemTime> for IggyTimestamp {
    type Output = IggyTimestamp;

    fn sub(self, rhs: SystemTime) -> Self::Output {
        IggyTimestamp(self.0 - rhs.duration_since(UNIX_EPOCH).unwrap())
    }
}

impl Add<IggyDuration> for IggyTimestamp {
    type Output = IggyTimestamp;

    fn add(self, other: IggyDuration) -> Self::Output {
        IggyTimestamp(self.0 + other.get_duration())
    }
}

impl Sub for IggyTimestamp {
    type Output = Duration;

    fn sub(self, rhs: Self) -> Self::Output {
        self.0
            .duration_since(rhs.0)
            .expect("Failed to subtract timestamps rhs < self")
    }
}

impl Default for IggyTimestamp {
    fn default() -> Self {
        Self(SystemTime::now())
    }
}

impl fmt::Display for IggyTimestamp {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.to_utc_string(UTC_TIME_FORMAT))
    }
}

impl Serialize for IggyTimestamp {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let timestamp = self.as_micros();
        serializer.serialize_u64(timestamp)
    }
}

impl<'de> Deserialize<'de> for IggyTimestamp {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_u64(IggyTimestampVisitor)
    }
}
struct IggyTimestampVisitor;

impl Visitor<'_> for IggyTimestampVisitor {
    type Value = IggyTimestamp;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("a microsecond timestamp as a u64")
    }

    fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        Ok(IggyTimestamp::from(value))
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_timestamp_get() {
        let timestamp = IggyTimestamp::now();
        assert!(timestamp.as_micros() > 0);
    }

    #[test]
    fn test_timestamp_to_micros() {
        let timestamp = IggyTimestamp::from(1663472051111);
        assert_eq!(timestamp.as_micros(), 1663472051111);
    }

    #[test]
    fn test_timestamp_to_string() {
        let timestamp = IggyTimestamp::from(1694968446131680);
        assert_eq!(
            timestamp.to_utc_string("%Y-%m-%d %H:%M:%S"),
            "2023-09-17 16:34:06"
        );
    }

    #[test]
    fn test_timestamp_from_u64() {
        let timestamp = IggyTimestamp::from(1663472051111);
        assert_eq!(timestamp.as_micros(), 1663472051111);
    }
}
