use std::collections::HashMap;
use std::sync::OnceLock;

use crate::datafile::feature_flag::FeatureFlag as InternalFeatureFlag;
use crate::types::{Rule, Variation};

static UNKNOWN_VARIATION: OnceLock<Variation> = OnceLock::new();

#[derive(Debug)]
#[cfg_attr(test, derive(PartialEq))]
pub struct FeatureFlag {
    pub environment_enabled: bool,
    pub default_variation_key: String,
    pub variations: HashMap<String, Variation>,
    pub rules: Vec<Rule>,
}

impl FeatureFlag {
    pub(crate) fn from_internal(feature_flag: &impl InternalFeatureFlag) -> Self {
        let variations = feature_flag
            .variations()
            .iter()
            .map(|(key, variation)| (key.clone(), Variation::from_internal(variation, None, None)))
            .collect();
        let rules = feature_flag.rules().iter().map(|rule| Rule::from_internal(rule, feature_flag)).collect();

        Self {
            environment_enabled: feature_flag.is_environment_enabled(),
            default_variation_key: feature_flag.default_variation_key().to_owned(),
            variations,
            rules,
        }
    }

    pub fn default_variation(&self) -> &Variation {
        self.variations
            .get(&self.default_variation_key)
            .unwrap_or_else(|| UNKNOWN_VARIATION.get_or_init(Variation::default))
    }
}
