// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
    anyhow::{format_err, Context as _, Error},
    serde::Deserialize,
    serde_json5,
    std::fs,
    std::path::Path,
};

/// Configuration for a single project to map inspect data to its cobalt metrics.
#[derive(Deserialize, Debug, PartialEq, Eq)]
pub struct ProjectConfig {
    /// Project ID that metrics are being sampled and forwarded on behalf of.
    pub project_id: u32,

    /// The frequency with which metrics are sampled, in seconds.
    pub poll_rate_sec: i64,

    /// The collection of mappings from inspect to cobalt.
    pub metrics: Vec<MetricConfig>,
}

/// Configuration for a single metric to map from an inspect property
/// to a cobalt metric.
#[derive(Deserialize, Debug, PartialEq, Eq)]
pub struct MetricConfig {
    pub selector: String,
    pub metric_id: u32,
    pub metric_type: DataType,
    pub event_codes: Vec<u32>,
}

/// The supported V1.0 Cobalt Metrics
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
pub enum DataType {
    // Maps cached diffs from Uint or Int inspect types.
    // NOTE: This does not use duration tracking. Durations
    //       are always set to 0.
    EventCount,
    // Maps raw Int inspect types.
    Int,
    // TODO(lukenicholson): Expand sampler support for new
    // data types.
    // Maps cached diffs from IntHistogram inspect type.
    // IntHistogram,
    // Maps raw Double inspect types.
    // FloatCustomEvent,
    // Maps raw Uint inspect types.
    // IndexCustomEvent,
}

/// Parses a configuration file for a single project into a ProjectConfig.
pub fn parse_config(path: impl AsRef<Path>) -> Result<ProjectConfig, Error> {
    let path = path.as_ref();
    let json_string: String =
        fs::read_to_string(path).with_context(|| format!("parsing config: {}", path.display()))?;
    let config: ProjectConfig = serde_json5::from_str(&json_string)?;
    Ok(config)
}

/// Container for all configurations needed to instantiate the Sampler infrastructure.
/// Includes:
///      - Project configurations.
///      - Minimum sample rate.
pub struct SamplerConfig {
    pub project_configs: Vec<ProjectConfig>,
    pub minimum_sample_rate_sec: i64,
}

impl SamplerConfig {
    /// Parse the ProjectConfigurations for every project from config data.
    pub fn from_directory(
        minimum_sample_rate_sec: i64,
        dir: impl AsRef<Path>,
    ) -> Result<Self, Error> {
        let suffix = std::ffi::OsStr::new("json");
        let readdir = dir.as_ref().read_dir();
        let mut project_configs: Vec<ProjectConfig> = Vec::new();
        match readdir {
            Err(e) => {
                return Err(format_err!(
                    "Failed to read directory {}, Error: {:?}",
                    dir.as_ref().to_string_lossy(),
                    e
                ));
            }
            Ok(mut readdir) => {
                while let Some(Ok(entry)) = readdir.next() {
                    let path = entry.path();
                    if path.extension() == Some(&suffix) {
                        match parse_config(&path) {
                            Ok(project_config) => {
                                project_configs.push(project_config);
                            }
                            Err(e) => {
                                return Err(format_err!(
                                    "Failed to parse {}: {}",
                                    path.to_string_lossy(),
                                    e.to_string()
                                ));
                            }
                        }
                    }
                }
            }
        }
        Ok(Self { minimum_sample_rate_sec, project_configs })
    }
}

#[cfg(test)]
mod tests {
    use super::SamplerConfig;
    use std::fs;
    #[test]
    fn parse_valid_configs() {
        let dir = tempfile::tempdir().unwrap();
        let config_path = dir.path().join("config");
        fs::create_dir(&config_path).unwrap();
        fs::write(config_path.join("ok.json"), r#"{
  "project_id": 5,
  "poll_rate_sec": 60,
  "metrics": [
    {
      // Test comment for json5 portability.
      "selector": "bootstrap/archivist:root/all_archive_accessor:inspect_batch_iterator_get_next_requests",
      "metric_id": 1,
      "metric_type": "EventCount",
      "event_codes": [0, 0]
    }
  ]
}
"#).unwrap();
        fs::write(config_path.join("ignored.txt"), "This file is ignored").unwrap();
        fs::write(
            config_path.join("also_ok.json"),
            r#"{
  "project_id": 5,
  "poll_rate_sec": 3,
  "metrics": [
    {
      "selector": "single_counter_test_component.cmx:root:counter",
      "metric_id": 1,
      "metric_type": "EventCount",
      "event_codes": [0, 0]
    }
  ]
}
"#,
        )
        .unwrap();

        let config = SamplerConfig::from_directory(10, &config_path);
        assert!(config.is_ok());
        assert_eq!(config.unwrap().project_configs.len(), 2);
    }

    #[test]
    fn parse_one_valid_one_invalid_config() {
        let dir = tempfile::tempdir().unwrap();
        let config_path = dir.path().join("config");
        fs::create_dir(&config_path).unwrap();
        fs::write(config_path.join("ok.json"), r#"{
  "project_id": 5,
  "poll_rate_sec": 60,
  "metrics": [
    {
      // Test comment for json5 portability.
      "selector": "bootstrap/archivist:root/all_archive_accessor:inspect_batch_iterator_get_next_requests",
      "metric_id": 1,
      "metric_type": "EventCount",
      "event_codes": [0, 0]
    }
  ]
}
"#).unwrap();
        fs::write(config_path.join("ignored.txt"), "This file is ignored").unwrap();
        fs::write(
            config_path.join("invalid.json"),
            r#"{
  "project_id": 5,
  "poll_rate_sec": 3,
  "invalid_field": "bad bad bad"
}
"#,
        )
        .unwrap();

        let config = SamplerConfig::from_directory(10, &config_path);
        assert!(config.is_err());
    }
}
