//! Rhai bindings for Kubernetes module
//!
//! This module provides modular Rhai wrappers for Kubernetes operations,
//! enabling fluent API access to create and manage Kubernetes resources.
//!
//! ## Module Structure
//!
//! - `runtime`: Async runtime helpers
//! - `context`: Global Kubernetes context
//! - `namespace`: Namespace and resource builder wrappers
//! - `resources`: Resource builders (ConfigMap, Secret, Pod, Service)
//! - `registry`: Registry deployment wrappers
//! - `build_machine`: Build machine provisioning wrappers

pub mod build_machine;
pub mod context;
pub mod development_machine;
pub mod namespace;
pub mod registry;
pub mod resources;
pub mod runtime;

use rhai::Engine;

// Re-export main types for convenience
pub use build_machine::{BuildMachineHandleRhai, BuildMachineRhai};
pub use context::{KubernetesContextRhai, kubernetes};
pub use development_machine::DevelopmentMachineRhai;
pub use namespace::NamespaceRhai;
pub use registry::{RegistryDeployerBuilderRhai, RegistryDeployerRhai};
pub use resources::{ConfigMapRhai, PodRhai, SecretRhai, ServiceRhai};

/// Register the kubernetes module with the Rhai engine
pub fn register_kubernetes_module(engine: &mut Engine) -> Result<(), Box<rhai::EvalAltResult>> {
    // Register types
    engine.register_type::<KubernetesContextRhai>();
    engine.register_type::<NamespaceRhai>();
    engine.register_type::<ConfigMapRhai>();
    engine.register_type::<SecretRhai>();
    engine.register_type::<PodRhai>();
    engine.register_type::<ServiceRhai>();
    engine.register_type::<RegistryDeployerBuilderRhai>();
    engine.register_type::<RegistryDeployerRhai>();
    engine.register_type::<BuildMachineRhai>();
    engine.register_type::<BuildMachineHandleRhai>();
    engine.register_type::<DevelopmentMachineRhai>();

    // Register global function
    engine.register_fn("kubernetes", kubernetes);

    // Register KubernetesContext methods
    engine.register_fn("reset", |k: KubernetesContextRhai| k.reset());
    engine.register_fn("md", |k: KubernetesContextRhai| k.md());
    engine.register_fn("ns_list", |k: KubernetesContextRhai| k.ns_list());
    engine.register_fn("ns_delete", |k: KubernetesContextRhai, name: String| {
        k.ns_delete(&name)
    });
    engine.register_fn("namespace", |k: KubernetesContextRhai, name: String| {
        k.namespace(&name)
    });

    // Register NamespaceRhai methods
    engine.register_fn("reset", |ns: NamespaceRhai| ns.reset());
    engine.register_fn("md", |ns: NamespaceRhai| ns.md());
    engine.register_fn("pods_list", |ns: NamespaceRhai| ns.pods_list());
    engine.register_fn("deployments_list", |ns: NamespaceRhai| {
        ns.deployments_list()
    });
    engine.register_fn("services_list", |ns: NamespaceRhai| ns.services_list());
    engine.register_fn("secrets_list", |ns: NamespaceRhai| ns.secrets_list());
    engine.register_fn("configmaps_list", |ns: NamespaceRhai| ns.configmaps_list());
    engine.register_fn("configmap", |ns: NamespaceRhai, name: String| {
        ns.configmap(&name)
    });
    engine.register_fn("secret", |ns: NamespaceRhai, name: String| ns.secret(&name));
    engine.register_fn("pod", |ns: NamespaceRhai, name: String| ns.pod(&name));
    engine.register_fn("service", |ns: NamespaceRhai, name: String| {
        ns.service(&name)
    });
    engine.register_fn("registry", |ns: NamespaceRhai, name: String| {
        ns.registry(&name)
    });
    engine.register_fn("build_machine", |ns: NamespaceRhai, name: String| {
        ns.build_machine(&name)
    });
    engine.register_fn("development_machine", |ns: NamespaceRhai, name: String| {
        ns.development_machine(&name)
    });
    engine.register_fn("registry_delete", |ns: NamespaceRhai, name: String| {
        ns.registry_delete(&name)
    });
    engine.register_fn("delete", |ns: NamespaceRhai| ns.delete());

    // Register ConfigMapRhai methods
    engine.register_fn("set", |cm: ConfigMapRhai, key: String, value: String| {
        cm.set(&key, &value)
    });
    engine.register_fn("apply", |cm: ConfigMapRhai| cm.apply());

    // Register SecretRhai methods
    engine.register_fn("set", |secret: SecretRhai, key: String, value: String| {
        secret.set(&key, &value)
    });
    engine.register_fn("apply", |secret: SecretRhai| secret.apply());

    // Register PodRhai methods
    engine.register_fn("image", |pod: PodRhai, image: String| pod.image(&image));
    engine.register_fn("env", |pod: PodRhai, key: String, value: String| {
        pod.env(&key, &value)
    });
    engine.register_fn("label", |pod: PodRhai, key: String, value: String| {
        pod.label(&key, &value)
    });
    engine.register_fn("port", |pod: PodRhai, port: i64| pod.port(port));
    engine.register_fn("memory", |pod: PodRhai, requested: i64, limit: i64| {
        pod.memory(requested, limit)
    });
    engine.register_fn("cpu", |pod: PodRhai, requested: i64, limit: i64| {
        pod.cpu(requested, limit)
    });
    engine.register_fn("apply", |pod: PodRhai| pod.apply());
    engine.register_fn("do", |pod: PodRhai| pod.do_());

    // Register ServiceRhai methods
    engine.register_fn(
        "selector",
        |svc: ServiceRhai, key: String, value: String| svc.selector(&key, &value),
    );
    engine.register_fn("expose", |svc: ServiceRhai, port: i64| svc.expose(port));
    engine.register_fn("to_container", |svc: ServiceRhai, port: i64| {
        svc.to_container(port)
    });
    engine.register_fn("to", |svc: ServiceRhai, port: i64| svc.to(port));
    engine.register_fn("nodeport", |svc: ServiceRhai| svc.nodeport());
    engine.register_fn("via_node", |svc: ServiceRhai, node_port: i64| {
        svc.via_node(node_port)
    });
    engine.register_fn("apply", |svc: ServiceRhai| svc.apply());
    engine.register_fn("do", |svc: ServiceRhai| svc.do_());

    // Register RegistryDeployerBuilderRhai methods
    engine.register_fn(
        "node_port",
        |builder: RegistryDeployerBuilderRhai, port: i64| builder.node_port(port),
    );
    engine.register_fn(
        "timeout",
        |builder: RegistryDeployerBuilderRhai, secs: i64| builder.timeout(secs),
    );
    engine.register_fn(
        "storage_size",
        |builder: RegistryDeployerBuilderRhai, size: i64| builder.storage_size(size),
    );
    engine.register_fn("deploy", |builder: RegistryDeployerBuilderRhai| {
        builder.deploy()
    });

    // Register RegistryDeployerRhai methods
    engine.register_fn("connection_string", |deployer: RegistryDeployerRhai| {
        deployer.connection_string()
    });
    engine.register_fn(
        "external_connection_string",
        |deployer: RegistryDeployerRhai| deployer.external_connection_string(),
    );
    engine.register_fn("image_prefix", |deployer: RegistryDeployerRhai| {
        deployer.image_prefix()
    });
    engine.register_fn("external_image_prefix", |deployer: RegistryDeployerRhai| {
        deployer.external_image_prefix()
    });
    engine.register_fn("name", |deployer: RegistryDeployerRhai| deployer.name());
    engine.register_fn("namespace", |deployer: RegistryDeployerRhai| {
        deployer.namespace()
    });
    engine.register_fn("port", |deployer: RegistryDeployerRhai| deployer.port());
    engine.register_fn("node_port", |deployer: RegistryDeployerRhai| {
        deployer.node_port()
    });

    // Register BuildMachineRhai methods
    engine.register_fn("image", |bm: BuildMachineRhai, image: String| {
        bm.image(&image)
    });
    engine.register_fn(
        "memory",
        |bm: BuildMachineRhai, requested: i64, limit: i64| bm.memory(requested, limit),
    );
    engine.register_fn("cpu", |bm: BuildMachineRhai, requested: i64, limit: i64| {
        bm.cpu(requested, limit)
    });
    engine.register_fn("privileged", |bm: BuildMachineRhai, privileged: bool| {
        bm.privileged(privileged)
    });
    engine.register_fn("provision", |bm: BuildMachineRhai| bm.provision());

    // Register BuildMachineHandleRhai methods
    engine.register_fn("namespace", |handle: BuildMachineHandleRhai| {
        handle.namespace()
    });
    engine.register_fn("pod_name", |handle: BuildMachineHandleRhai| {
        handle.pod_name()
    });
    engine.register_fn("destroy", |handle: BuildMachineHandleRhai| handle.destroy());

    // Register DevelopmentMachineRhai methods
    engine.register_fn("namespace", |dev: DevelopmentMachineRhai, namespace: String| {
        dev.namespace(&namespace)
    });
    engine.register_fn("image", |dev: DevelopmentMachineRhai, image: String| {
        dev.image(&image)
    });
    engine.register_fn("cpu", |dev: DevelopmentMachineRhai, request: i64, limit: i64| {
        dev.cpu(request, limit)
    });
    engine.register_fn("memory", |dev: DevelopmentMachineRhai, request: i64, limit: i64| {
        dev.memory(request, limit)
    });
    engine.register_fn("env", |dev: DevelopmentMachineRhai, key: String, value: String| {
        dev.env(&key, &value)
    });
    engine.register_fn("env_from_configmap", |dev: DevelopmentMachineRhai, configmap: String| {
        dev.env_from_configmap(&configmap)
    });
    engine.register_fn("env_from_secret", |dev: DevelopmentMachineRhai, secret: String| {
        dev.env_from_secret(&secret)
    });
    engine.register_fn("label", |dev: DevelopmentMachineRhai, key: String, value: String| {
        dev.label(&key, &value)
    });
    engine.register_fn("port", |dev: DevelopmentMachineRhai, port: i64| {
        dev.port(port)
    });
    engine.register_fn("readiness_http", |dev: DevelopmentMachineRhai, path: String, port: i64| {
        dev.readiness_http(&path, port)
    });
    engine.register_fn("liveness_http", |dev: DevelopmentMachineRhai, path: String, port: i64| {
        dev.liveness_http(&path, port)
    });
    engine.register_fn("readiness_tcp", |dev: DevelopmentMachineRhai, port: i64| {
        dev.readiness_tcp(port)
    });
    engine.register_fn("liveness_tcp", |dev: DevelopmentMachineRhai, port: i64| {
        dev.liveness_tcp(port)
    });
    engine.register_fn("initial_delay", |dev: DevelopmentMachineRhai, seconds: i64| {
        dev.initial_delay(seconds)
    });
    engine.register_fn("period", |dev: DevelopmentMachineRhai, seconds: i64| {
        dev.period(seconds)
    });
    engine.register_fn("failure_threshold", |dev: DevelopmentMachineRhai, count: i64| {
        dev.failure_threshold(count)
    });
    engine.register_fn("restart", |dev: DevelopmentMachineRhai, policy: String| {
        dev.restart(&policy)
    });
    engine.register_fn("reset", |dev: DevelopmentMachineRhai, reset: bool| {
        dev.reset(reset)
    });
    engine.register_fn("secret_name", |dev: DevelopmentMachineRhai, secret_name: String| {
        dev.secret_name(&secret_name)
    });
    engine.register_fn("deploy", |dev: DevelopmentMachineRhai| dev.deploy());
    engine.register_fn("get_ssh_key", |dev: DevelopmentMachineRhai| dev.get_ssh_key());
    engine.register_fn("get_ssh_public_key", |dev: DevelopmentMachineRhai| {
        dev.get_ssh_public_key()
    });
    engine.register_fn("get_name", |dev: DevelopmentMachineRhai| dev.get_name());
    engine.register_fn("get_namespace", |dev: DevelopmentMachineRhai| dev.get_namespace());
    engine.register_fn("get_image", |dev: DevelopmentMachineRhai| dev.get_image());

    Ok(())
}
