//! Service registry configuration for operation context

use serde::{Deserialize, Serialize};
use std::collections::HashMap;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServiceRegistry {
    pub services: HashMap<String, ServiceDefinition>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServiceDefinition {
    pub name: String,
    pub description: String,
    pub operations: HashMap<String, OperationConfig>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OperationConfig {
    pub operation: String,
    pub description: String,
    pub required_params: Vec<String>,
    pub optional_params: Vec<String>,
    pub confidential_data: Vec<String>,
    pub non_confidential_data: Vec<String>,
    pub validation_rules: HashMap<String, ValidationRule>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValidationRule {
    #[serde(rename = "type")]
    pub rule_type: String,
    pub pattern: Option<String>,
    pub enum_values: Option<Vec<String>>,
    pub min_length: Option<usize>,
    pub max_length: Option<usize>,
}

impl ServiceRegistry {
    pub fn default() -> Self {
        let mut services = HashMap::new();

        // AWS EC2 Service
        let mut ec2_operations = HashMap::new();
        
        ec2_operations.insert("stop_instance".to_string(), OperationConfig {
            operation: "stop_instance".to_string(),
            description: "Stop an EC2 instance".to_string(),
            required_params: vec!["instance_id".to_string(), "region".to_string()],
            optional_params: vec!["force".to_string()],
            confidential_data: vec!["name".to_string(), "tags".to_string(), "security_groups".to_string()],
            non_confidential_data: vec!["region".to_string(), "state".to_string(), "instance_type".to_string()],
            validation_rules: HashMap::new(),
        });

        ec2_operations.insert("start_instance".to_string(), OperationConfig {
            operation: "start_instance".to_string(),
            description: "Start an EC2 instance".to_string(),
            required_params: vec!["instance_id".to_string(), "region".to_string()],
            optional_params: vec![],
            confidential_data: vec!["name".to_string(), "tags".to_string(), "security_groups".to_string()],
            non_confidential_data: vec!["region".to_string(), "state".to_string(), "instance_type".to_string()],
            validation_rules: HashMap::new(),
        });

        services.insert("aws_ec2".to_string(), ServiceDefinition {
            name: "aws_ec2".to_string(),
            description: "Amazon EC2 (Elastic Compute Cloud) service for managing virtual machines".to_string(),
            operations: ec2_operations,
        });

        // AWS RDS Service
        let mut rds_operations = HashMap::new();
        
        rds_operations.insert("stop_db_instance".to_string(), OperationConfig {
            operation: "stop_db_instance".to_string(),
            description: "Stop an RDS database instance".to_string(),
            required_params: vec!["db_instance_identifier".to_string(), "region".to_string()],
            optional_params: vec!["snapshot_id".to_string()],
            confidential_data: vec!["db_name".to_string(), "master_username".to_string(), "endpoint".to_string()],
            non_confidential_data: vec!["region".to_string(), "engine".to_string(), "db_instance_class".to_string()],
            validation_rules: HashMap::new(),
        });

        rds_operations.insert("start_db_instance".to_string(), OperationConfig {
            operation: "start_db_instance".to_string(),
            description: "Start an RDS database instance".to_string(),
            required_params: vec!["db_instance_identifier".to_string(), "region".to_string()],
            optional_params: vec![],
            confidential_data: vec!["db_name".to_string(), "master_username".to_string(), "endpoint".to_string()],
            non_confidential_data: vec!["region".to_string(), "engine".to_string(), "db_instance_class".to_string()],
            validation_rules: HashMap::new(),
        });

        services.insert("aws_rds".to_string(), ServiceDefinition {
            name: "aws_rds".to_string(),
            description: "Amazon RDS (Relational Database Service) for managed databases".to_string(),
            operations: rds_operations,
        });

        // AWS S3 Service
        let mut s3_operations = HashMap::new();
        
        s3_operations.insert("delete_bucket".to_string(), OperationConfig {
            operation: "delete_bucket".to_string(),
            description: "Delete an S3 bucket".to_string(),
            required_params: vec!["bucket".to_string(), "region".to_string()],
            optional_params: vec!["force".to_string()],
            confidential_data: vec!["bucket_name".to_string(), "policy".to_string()],
            non_confidential_data: vec!["region".to_string(), "versioning_status".to_string()],
            validation_rules: HashMap::new(),
        });

        services.insert("aws_s3".to_string(), ServiceDefinition {
            name: "aws_s3".to_string(),
            description: "Amazon S3 (Simple Storage Service) for object storage".to_string(),
            operations: s3_operations,
        });

        Self { services }
    }

    pub fn get_service(&self, service_name: &str) -> Option<&ServiceDefinition> {
        self.services.get(service_name)
    }

    pub fn get_operation_config(&self, service_name: &str, operation_name: &str) -> Option<&OperationConfig> {
        self.services
            .get(service_name)?
            .operations
            .get(operation_name)
    }

    pub fn get_all_services(&self) -> Vec<&str> {
        self.services.keys().map(|s| s.as_str()).collect()
    }

    pub fn get_service_operations(&self, service_name: &str) -> Vec<&str> {
        self.services
            .get(service_name)
            .map(|service| service.operations.keys().map(|op| op.as_str()).collect())
            .unwrap_or_default()
    }
}