use std::path::{Path, PathBuf};

use async_trait::async_trait;
use serde::Serialize;

use crate::{
    data::{Id, Version},
    interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome},
    inventory::Inventory,
    modules::k8s::deployment::K8sDeploymentScore,
    score::Score,
    topology::{OcK8sclient, Topology, Url},
};

#[derive(Debug, Clone, Serialize)]
pub struct LAMPScore {
    pub name: String,
    pub domain: Url,
    pub config: LAMPConfig,
    pub php_version: Version,
}

#[derive(Debug, Clone, Serialize)]
pub struct LAMPConfig {
    pub project_root: PathBuf,
    pub ssl_enabled: bool,
}

impl Default for LAMPConfig {
    fn default() -> Self {
        LAMPConfig {
            project_root: Path::new("./src").to_path_buf(),
            ssl_enabled: true,
        }
    }
}

impl<T: Topology> Score<T> for LAMPScore {
    fn create_interpret(&self) -> Box<dyn Interpret<T>> {
        todo!()
    }

    fn name(&self) -> String {
        "LampScore".to_string()
    }
}

#[derive(Debug)]
pub struct LAMPInterpret {
    score: LAMPScore,
}

#[async_trait]
impl<T: Topology + OcK8sclient> Interpret<T> for LAMPInterpret {
    async fn execute(
        &self,
        inventory: &Inventory,
        topology: &T,
    ) -> Result<Outcome, InterpretError> {
        let deployment_score = K8sDeploymentScore {
            name: <LAMPScore as Score<T>>::name(&self.score),
            image: "local_image".to_string(),
        };

        deployment_score
            .create_interpret()
            .execute(inventory, topology)
            .await?;
        todo!()
    }

    fn get_name(&self) -> InterpretName {
        todo!()
    }

    fn get_version(&self) -> Version {
        todo!()
    }

    fn get_status(&self) -> InterpretStatus {
        todo!()
    }

    fn get_children(&self) -> Vec<Id> {
        todo!()
    }
}
