use std::sync::Arc;

use async_trait::async_trait;
use dagger_sdk::Container;

use crate::dagger_middleware::DaggerMiddleware;

use super::RustService;

pub struct Kubectl {
    client: dagger_sdk::Query,
}

impl Kubectl {
    pub fn new(client: dagger_sdk::Query) -> Self {
        Self { client }
    }
}

const KUBESLICEDOWNLOAD: &str = r#"slice_VERSION=v1.2.7 && \
wget -O kubectl-slice_linux_x86_64.tar.gz "https://github.com/patrickdappollonio/kubectl-slice/releases/download/$slice_VERSION/kubectl-slice_linux_x86_64.tar.gz" &&  \
tar -xf kubectl-slice_linux_x86_64.tar.gz && \
chmod +x ./kubectl-slice && \
mv ./kubectl-slice /usr/local/bin/kubectl-slice && \
rm kubectl-slice_linux_x86_64.tar.gz"#;

#[async_trait]
impl DaggerMiddleware for Kubectl {
    async fn handle(&self, container: Container) -> eyre::Result<Container> {
        let kubectl = self
            .client
            .container()
            .from("line/kubectl-kustomize:1.29.1-5.3.0");

        let kubeslice = self
            .client
            .container()
            .from("alpine:3.19")
            .with_exec(vec!["apk", "add", "tar", "wget"])
            .with_exec(vec!["sh", "-c", KUBESLICEDOWNLOAD]);

        let helm = self.client.container().from("alpine/helm:3.11.1");

        Ok(container
            .with_file(
                "/usr/local/bin/kubectl",
                kubectl.file("/usr/local/bin/kubectl"),
            )
            .with_file(
                "/usr/local/bin/kustomize",
                kubectl.file("/usr/local/bin/kustomize"),
            )
            .with_file(
                "/usr/local/bin/kubectl-slice",
                kubeslice.file("/usr/local/bin/kubectl-slice"),
            )
            .with_file("/usr/local/bin/helm", helm.file("/usr/bin/helm")))
    }
}

pub trait KubectlExt {
    fn with_kubectl(&mut self) -> &mut Self {
        self
    }
}

impl KubectlExt for RustService {
    fn with_kubectl(&mut self) -> &mut Self {
        self.with_stage(super::RustServiceStage::BeforePackage(Arc::new(
            Kubectl::new(self.client.clone()),
        )));

        self
    }
}
