//! Nightlight API Client Library
//!
//! This crate provides gRPC client interfaces for interacting with Nightlight,
//! a Prometheus-compatible metrics storage system with mTLS support.
//!
//! # Features
//!
//! - **Remote Write**: Push metrics using the Prometheus remote write protocol
//! - **PromQL Queries**: Execute instant and range queries with PromQL
//! - **Admin API**: Health checks, statistics, and server information
//!
//! # Example: Writing Metrics
//!
//! ```rust,no_run
//! use nightlight_api::prometheus::{WriteRequest, TimeSeries, Label, Sample};
//!
//! // Create a write request with sample data
//! let request = WriteRequest {
//!     timeseries: vec![
//!         TimeSeries {
//!             labels: vec![
//!                 Label { name: "__name__".to_string(), value: "http_requests_total".to_string() },
//!                 Label { name: "method".to_string(), value: "GET".to_string() },
//!             ],
//!             samples: vec![
//!                 Sample { value: 42.0, timestamp: 1234567890000 },
//!             ],
//!         },
//!     ],
//! };
//! ```
//!
//! # Example: Querying Metrics
//!
//! ```rust,no_run
//! use nightlight_api::nightlight::{InstantQueryRequest, RangeQueryRequest};
//!
//! // Instant query at current time
//! let instant = InstantQueryRequest {
//!     query: "http_requests_total{method='GET'}".to_string(),
//!     time: 0,  // Use current time
//!     timeout: 5000,  // 5 second timeout
//! };
//!
//! // Range query over 1 hour with 1 minute resolution
//! let range = RangeQueryRequest {
//!     query: "rate(http_requests_total[5m])".to_string(),
//!     start: 1234567890000,
//!     end: 1234571490000,
//!     step: 60000,  // 1 minute
//!     timeout: 10000,
//! };
//! ```

// Include generated protobuf code
// The tonic::include_proto! macro includes the generated code from OUT_DIR
pub mod prometheus {
    //! Prometheus remote write protocol types
    //!
    //! This module contains the protobuf definitions for Prometheus remote write,
    //! which is the standard protocol for pushing metrics to TSDB systems.
    tonic::include_proto!("prometheus");
}

pub mod nightlight {
    //! Nightlight-specific API types
    //!
    //! This module contains the PromQL query API and admin endpoints.
    tonic::include_proto!("nightlight");
}

// Re-export commonly used types for convenience
pub use prometheus::{Label, Sample, TimeSeries, WriteRequest};
pub use nightlight::{
    InstantQueryRequest, QueryResponse, RangeQueryRequest,
    HealthRequest, HealthResponse, StatsRequest, StatsResponse,
};

// Re-export gRPC clients for external use
pub use nightlight::{
    metric_query_client::MetricQueryClient,
    admin_client::AdminClient,
};

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

    #[test]
    fn test_create_write_request() {
        // Verify that we can construct basic protobuf messages
        let label = Label {
            name: "__name__".to_string(),
            value: "test_metric".to_string(),
        };

        let sample = Sample {
            value: 1.0,
            timestamp: 1234567890000,
        };

        let series = TimeSeries {
            labels: vec![label],
            samples: vec![sample],
        };

        let request = WriteRequest {
            timeseries: vec![series],
        };

        assert_eq!(request.timeseries.len(), 1);
        assert_eq!(request.timeseries[0].labels.len(), 1);
        assert_eq!(request.timeseries[0].samples.len(), 1);
    }

    #[test]
    fn test_create_instant_query() {
        let query = InstantQueryRequest {
            query: "up".to_string(),
            time: 0,
            timeout: 5000,
        };

        assert_eq!(query.query, "up");
    }

    #[test]
    fn test_create_range_query() {
        let query = RangeQueryRequest {
            query: "rate(http_requests_total[5m])".to_string(),
            start: 1000,
            end: 2000,
            step: 100,
            timeout: 10000,
        };

        assert_eq!(query.start, 1000);
        assert_eq!(query.end, 2000);
        assert_eq!(query.step, 100);
    }
}
