Documentation
// Copyright (c) 2025, Salesforce, Inc.,
// All rights reserved.
// For full license text, see the LICENSE.txt file

use crate::services::flex::gcl::ToGcl;
use serde::Serialize;

/// Configuration for a local API service.
#[derive(Debug, Clone)]
pub struct PolicyConfig {
    name: String,
    config: String,
}

impl PolicyConfig {
    fn new() -> Self {
        Self {
            name: "test-policy".to_string(),
            config: "{}".to_string(),
        }
    }

    /// Creates a builder for initialize a [`PolicyConfig`].
    pub fn builder() -> PolicyConfigBuilder {
        PolicyConfigBuilder::new()
    }
}

/// A builder for initilizing a [`PolicyConfig`].
#[derive(Debug, Clone)]
pub struct PolicyConfigBuilder {
    config: PolicyConfig,
}

impl PolicyConfigBuilder {
    fn new() -> Self {
        Self {
            config: PolicyConfig::new(),
        }
    }

    /// Set the policy name.
    pub fn name<T: Into<String>>(self, name: T) -> Self {
        Self {
            config: PolicyConfig {
                name: name.into(),
                ..self.config
            },
        }
    }

    /// Set the policy configuration.
    pub fn configuration<T: Serialize>(self, config: T) -> Self {
        Self {
            config: PolicyConfig {
                config: serde_json::to_string(&config).unwrap_or_else(|_| "{}".to_string()),
                ..self.config
            },
        }
    }

    /// Builds a new [`PolicyConfig`].
    pub fn build(self) -> PolicyConfig {
        self.config
    }
}

impl ToGcl for PolicyConfig {
    // NOTE: If in the future we need to support non-compact policy GCLs (to apply policies to
    // services) we'll need change the api GCL to the non-compact one.
    fn to_gcl(&self) -> String {
        let name = self.name.as_str();
        let config = self.config.as_str();
        format!(
            r#"
    - policyRef:
        name: {name}
        namespace: default
      config: {config}"#
        )
    }

    fn name(&self) -> &str {
        &self.name
    }
}