// 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 crate::duration::iggy_duration_to_py_delta;
use iggy::prelude::{
    CacheMetrics as RustCacheMetrics, CacheMetricsKey as RustCacheMetricsKey, Stats as RustStats,
};
use pyo3::prelude::*;
use pyo3::types::{PyDelta, PyDict};
use pyo3_stub_gen::derive::{gen_stub_pyclass, gen_stub_pymethods};

/// Key identifying the partition a `CacheMetrics` entry belongs to.
///
/// Hashable and comparable, so it can key the `Stats.cache_metrics` dict.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[gen_stub_pyclass]
#[pyclass(eq, frozen, hash, skip_from_py_object)]
pub struct CacheMetricsKey {
    /// The unique identifier (numeric) of the stream.
    #[pyo3(get)]
    pub stream_id: u32,
    /// The unique identifier (numeric) of the topic within the stream.
    #[pyo3(get)]
    pub topic_id: u32,
    /// The unique identifier (numeric) of the partition within the topic.
    #[pyo3(get)]
    pub partition_id: u32,
}

impl From<&RustCacheMetricsKey> for CacheMetricsKey {
    fn from(key: &RustCacheMetricsKey) -> Self {
        Self {
            stream_id: key.stream_id,
            topic_id: key.topic_id,
            partition_id: key.partition_id,
        }
    }
}

#[gen_stub_pymethods]
#[pymethods]
impl CacheMetricsKey {
    #[new]
    fn new(stream_id: u32, topic_id: u32, partition_id: u32) -> Self {
        Self {
            stream_id,
            topic_id,
            partition_id,
        }
    }

    fn __repr__(&self) -> String {
        format!(
            "CacheMetricsKey(stream_id={}, topic_id={}, partition_id={})",
            self.stream_id, self.topic_id, self.partition_id
        )
    }
}

/// Cache metrics for a specific partition.
#[gen_stub_pyclass]
#[pyclass]
pub struct CacheMetrics {
    /// Number of cache hits.
    #[pyo3(get)]
    pub hits: u64,
    /// Number of cache misses.
    #[pyo3(get)]
    pub misses: u64,
    /// Hit ratio (hits / (hits + misses)).
    #[pyo3(get)]
    pub hit_ratio: f32,
}

impl From<&RustCacheMetrics> for CacheMetrics {
    fn from(metrics: &RustCacheMetrics) -> Self {
        Self {
            hits: metrics.hits,
            misses: metrics.misses,
            hit_ratio: metrics.hit_ratio,
        }
    }
}

#[gen_stub_pymethods]
#[pymethods]
impl CacheMetrics {
    fn __repr__(&self) -> String {
        format!(
            "CacheMetrics(hits={}, misses={}, hit_ratio={})",
            self.hits, self.misses, self.hit_ratio
        )
    }
}

/// The statistics and details of the server and its running process.
///
/// The fields are gathered from several sources while the request is served
/// (metadata counters, a process probe, a disk probe), so they are not an
/// atomic snapshot of one instant.
#[gen_stub_pyclass]
#[pyclass]
pub struct Stats {
    pub(crate) inner: RustStats,
}

impl From<RustStats> for Stats {
    fn from(stats: RustStats) -> Self {
        Self { inner: stats }
    }
}

#[gen_stub_pymethods]
#[pymethods]
impl Stats {
    /// The unique identifier of the server process.
    #[getter]
    pub fn process_id(&self) -> u32 {
        self.inner.process_id
    }

    /// The CPU usage of the server process, in percent summed over the cores
    /// it ran on, so it exceeds 100 whenever the process uses more than one
    /// core.
    ///
    /// Measured as a delta since the previous `get_stats` served by the same
    /// server shard, so the first sample a shard serves is 0.
    #[getter]
    pub fn cpu_usage(&self) -> f32 {
        self.inner.cpu_usage
    }

    /// The total CPU usage of the system, in percent averaged over the cores
    /// the server may run on when confined by an affinity/cpuset mask (over
    /// every host core otherwise), so it stays within 0-100.
    ///
    /// Same per-shard delta sampling as `cpu_usage`: the first sample a shard
    /// serves is 0.
    #[getter]
    pub fn total_cpu_usage(&self) -> f32 {
        self.inner.total_cpu_usage
    }

    /// The memory usage of the server process, in bytes.
    #[getter]
    pub fn memory_usage(&self) -> u64 {
        self.inner.memory_usage.as_bytes_u64()
    }

    /// The total memory of the system, in bytes, or the effective cgroup memory
    /// limit when the server runs inside a memory-capped cgroup (container,
    /// systemd slice).
    #[getter]
    pub fn total_memory(&self) -> u64 {
        self.inner.total_memory.as_bytes_u64()
    }

    /// The available memory of the system, in bytes, scoped to the cgroup
    /// limit when one applies.
    #[getter]
    pub fn available_memory(&self) -> u64 {
        self.inner.available_memory.as_bytes_u64()
    }

    /// The run time of the server process, with whole-second precision.
    #[getter]
    #[gen_stub(override_return_type(type_repr = "datetime.timedelta", imports=("datetime")))]
    pub fn run_time<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyDelta>> {
        iggy_duration_to_py_delta(py, self.inner.run_time)
    }

    /// The start time of the server process, in microseconds since the Unix
    /// epoch, with whole-second precision.
    #[getter]
    pub fn start_time(&self) -> u64 {
        self.inner.start_time.as_micros()
    }

    /// The total number of bytes read.
    #[getter]
    pub fn read_bytes(&self) -> u64 {
        self.inner.read_bytes.as_bytes_u64()
    }

    /// The total number of bytes written.
    #[getter]
    pub fn written_bytes(&self) -> u64 {
        self.inner.written_bytes.as_bytes_u64()
    }

    /// The total size of the messages, in bytes.
    #[getter]
    pub fn messages_size_bytes(&self) -> u64 {
        self.inner.messages_size_bytes.as_bytes_u64()
    }

    /// The total number of streams.
    #[getter]
    pub fn streams_count(&self) -> u32 {
        self.inner.streams_count
    }

    /// The total number of topics.
    #[getter]
    pub fn topics_count(&self) -> u32 {
        self.inner.topics_count
    }

    /// The total number of partitions.
    #[getter]
    pub fn partitions_count(&self) -> u32 {
        self.inner.partitions_count
    }

    /// The total number of segments.
    #[getter]
    pub fn segments_count(&self) -> u32 {
        self.inner.segments_count
    }

    /// The total number of messages.
    #[getter]
    pub fn messages_count(&self) -> u64 {
        self.inner.messages_count
    }

    /// The total number of connected clients.
    #[getter]
    pub fn clients_count(&self) -> u32 {
        self.inner.clients_count
    }

    /// The total number of consumer groups.
    #[getter]
    pub fn consumer_groups_count(&self) -> u32 {
        self.inner.consumer_groups_count
    }

    /// The name of the host the server runs on.
    #[getter]
    pub fn hostname(&self) -> String {
        self.inner.hostname.clone()
    }

    /// The name of the operating system.
    #[getter]
    pub fn os_name(&self) -> String {
        self.inner.os_name.clone()
    }

    /// The version of the operating system.
    #[getter]
    pub fn os_version(&self) -> String {
        self.inner.os_version.clone()
    }

    /// The version of the kernel.
    #[getter]
    pub fn kernel_version(&self) -> String {
        self.inner.kernel_version.clone()
    }

    /// The version of the Iggy server.
    #[getter]
    pub fn iggy_server_version(&self) -> String {
        self.inner.iggy_server_version.clone()
    }

    /// The numeric semantic version of the Iggy server, or `None` when unknown.
    /// E.g. 1.2.3 -> 1002003 (major * 1000000 + minor * 1000 + patch).
    #[getter]
    #[gen_stub(override_return_type(type_repr = "builtins.int | None"))]
    pub fn iggy_server_semver(&self) -> Option<u32> {
        self.inner.iggy_server_semver
    }

    /// Cache metrics per partition.
    ///
    /// Current servers do not populate this and reply with an empty map. Each
    /// access builds a fresh dict, so mutating the returned dict does not
    /// change the stats.
    #[getter]
    #[gen_stub(override_return_type(type_repr = "builtins.dict[CacheMetricsKey, CacheMetrics]"))]
    pub fn cache_metrics<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyDict>> {
        let dict = PyDict::new(py);
        for (key, metrics) in &self.inner.cache_metrics {
            dict.set_item(CacheMetricsKey::from(key), CacheMetrics::from(metrics))?;
        }
        Ok(dict)
    }

    /// The number of threads in the server process.
    #[getter]
    pub fn threads_count(&self) -> u32 {
        self.inner.threads_count
    }

    /// The available (free) disk space for the data directory, in bytes.
    ///
    /// 0 when the server does not know its data directory or the disk probe
    /// fails.
    #[getter]
    pub fn free_disk_space(&self) -> u64 {
        self.inner.free_disk_space.as_bytes_u64()
    }

    /// The total disk space for the data directory, in bytes.
    ///
    /// 0 when the server does not know its data directory or the disk probe
    /// fails.
    #[getter]
    pub fn total_disk_space(&self) -> u64 {
        self.inner.total_disk_space.as_bytes_u64()
    }

    fn __repr__(&self) -> String {
        format!(
            "Stats(hostname='{}', iggy_server_version='{}', streams_count={}, \
             topics_count={}, partitions_count={}, messages_count={}, clients_count={})",
            self.inner.hostname,
            self.inner.iggy_server_version,
            self.inner.streams_count,
            self.inner.topics_count,
            self.inner.partitions_count,
            self.inner.messages_count,
            self.inner.clients_count
        )
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use iggy::prelude::{IggyByteSize, IggyDuration, IggyTimestamp};
    use std::collections::HashMap;

    /// Two entries sharing a stream and topic, so a key collision in the
    /// `HashMap` -> `PyDict` conversion drops one of them.
    fn cache_metrics_entries() -> HashMap<RustCacheMetricsKey, RustCacheMetrics> {
        HashMap::from([
            (
                RustCacheMetricsKey {
                    stream_id: 1,
                    topic_id: 2,
                    partition_id: 3,
                },
                RustCacheMetrics {
                    hits: 7,
                    misses: 3,
                    hit_ratio: 0.7,
                },
            ),
            (
                RustCacheMetricsKey {
                    stream_id: 1,
                    topic_id: 2,
                    partition_id: 4,
                },
                RustCacheMetrics {
                    hits: 0,
                    misses: 5,
                    hit_ratio: 0.0,
                },
            ),
        ])
    }

    fn rust_stats(iggy_server_semver: Option<u32>) -> RustStats {
        RustStats {
            process_id: 1,
            cpu_usage: 0.0,
            total_cpu_usage: 0.0,
            memory_usage: IggyByteSize::default(),
            total_memory: IggyByteSize::default(),
            available_memory: IggyByteSize::default(),
            run_time: IggyDuration::default(),
            start_time: IggyTimestamp::default(),
            read_bytes: IggyByteSize::default(),
            written_bytes: IggyByteSize::default(),
            messages_size_bytes: IggyByteSize::default(),
            streams_count: 0,
            topics_count: 0,
            partitions_count: 0,
            segments_count: 0,
            messages_count: 0,
            clients_count: 0,
            consumer_groups_count: 0,
            hostname: String::new(),
            os_name: String::new(),
            os_version: String::new(),
            kernel_version: String::new(),
            iggy_server_version: String::new(),
            iggy_server_semver,
            cache_metrics: cache_metrics_entries(),
            threads_count: 0,
            free_disk_space: IggyByteSize::default(),
            total_disk_space: IggyByteSize::default(),
        }
    }

    #[test]
    fn given_stats_when_converting_should_preserve_semver_option() {
        Python::initialize();

        assert_eq!(Stats::from(rust_stats(None)).iggy_server_semver(), None);
        assert_eq!(
            Stats::from(rust_stats(Some(1_002_003))).iggy_server_semver(),
            Some(1_002_003)
        );
    }

    #[test]
    fn given_populated_cache_metrics_when_reading_should_key_every_entry() {
        Python::initialize();

        let stats = Stats::from(rust_stats(None));

        Python::attach(|py| {
            let dict = stats.cache_metrics(py).expect("build cache metrics dict");
            assert_eq!(dict.len(), cache_metrics_entries().len());

            let entry = dict
                .get_item(CacheMetricsKey::new(1, 2, 4))
                .expect("look up cache metrics entry")
                .expect("entry for an independently built key");
            assert_eq!(
                entry
                    .getattr("misses")
                    .and_then(|misses| misses.extract::<u64>())
                    .expect("read misses"),
                5
            );
        });
    }
}
