use std::sync::Arc;

use crate::{executors::ExecutorError, topology::k8s::K8sClient};
use async_trait::async_trait;
use derive_new::new;
use k8s_openapi::api::core::v1::Namespace;
use serde_json::json;

use super::{ResourceLimits, TenantConfig, TenantManager, TenantNetworkPolicy};

#[derive(new)]
pub struct K8sTenantManager {
    k8s_client: Arc<K8sClient>,
}

#[async_trait]
impl TenantManager for K8sTenantManager {
    async fn provision_tenant(&self, config: &TenantConfig) -> Result<(), ExecutorError> {
        let namespace = json!(
            {
                "apiVersion": "v1",
                "kind": "Namespace",
                "metadata": {
                    "labels": {
                        "harmony.nationtech.io/tenant.id": config.id,
                        "harmony.nationtech.io/tenant.name": config.name,
                    },
                "name": config.name,
                },
            }
        );
        todo!("Validate that when tenant already exists (by id) that name has not changed");

        let namespace: Namespace = serde_json::from_value(namespace).unwrap();

        let resource_quota = json!(
         {
           "apiVersion": "v1",
           "kind": "List",
           "items": [
             {
               "apiVersion": "v1",
               "kind": "ResourceQuota",
               "metadata": {
                 "name": config.name,
                 "labels": {
                  "harmony.nationtech.io/tenant.id": config.id,
                  "harmony.nationtech.io/tenant.name": config.name,
                 },
                 "namespace": config.name,
               },
               "spec": {
                 "hard": {
                   "limits.cpu": format!("{:.0}",config.resource_limits.cpu_limit_cores),
                   "limits.memory": format!("{:.3}Gi", config.resource_limits.memory_limit_gb),
                   "requests.cpu": format!("{:.0}",config.resource_limits.cpu_request_cores),
                   "requests.memory": format!("{:.3}Gi", config.resource_limits.memory_request_gb),
                   "requests.storage": format!("{:.3}", config.resource_limits.storage_total_gb),
                   "pods": "20",
                   "services": "10",
                   "configmaps": "30",
                   "secrets": "30",
                   "persistentvolumeclaims": "15",
                   "services.loadbalancers": "2",
                   "services.nodeports": "5",

                 }
               }
             }
           ]
         }

        );
    }

    async fn update_tenant_resource_limits(
        &self,
        tenant_name: &str,
        new_limits: &ResourceLimits,
    ) -> Result<(), ExecutorError> {
        todo!()
    }

    async fn update_tenant_network_policy(
        &self,
        tenant_name: &str,
        new_policy: &TenantNetworkPolicy,
    ) -> Result<(), ExecutorError> {
        todo!()
    }

    async fn deprovision_tenant(&self, tenant_name: &str) -> Result<(), ExecutorError> {
        todo!()
    }
}
