// Parmanode script runner - executes Parmanode installation scripts in containers
// Provides compatibility layer for existing Parmanode modules

use archipelago_container::PodmanClient;
use anyhow::{Context, Result};
use std::path::PathBuf;
use std::process::Command;
use tokio::fs;
use tracing::{info, warn};

pub struct ParmanodeScriptRunner {
    _podman: PodmanClient,
    _scripts_dir: PathBuf,
}

impl ParmanodeScriptRunner {
    pub fn new(scripts_dir: PathBuf) -> Self {
        Self {
            _podman: PodmanClient::new("archipelago".to_string()),
            _scripts_dir: scripts_dir,
        }
    }
    
    /// Detect if a path contains a Parmanode script
    pub fn is_parmanode_script(&self, path: &PathBuf) -> bool {
        // Check for common Parmanode script patterns
        path.file_name()
            .and_then(|name| name.to_str())
            .map(|name| {
                name.ends_with(".sh") && (
                    name.contains("parmanode") ||
                    name.contains("bitcoin") ||
                    name.contains("lightning") ||
                    name.contains("electrs")
                )
            })
            .unwrap_or(false)
    }
    
    /// Run a Parmanode script in an isolated container
    pub async fn run_script(&self, script_path: &PathBuf) -> Result<()> {
        info!("Running Parmanode script: {:?}", script_path);
        
        // Create a temporary container manifest for the script
        let script_name = script_path
            .file_stem()
            .and_then(|s| s.to_str())
            .unwrap_or("parmanode-script");
        
        // Create a minimal container to run the script
        let _container_name = format!("parmanode-{}", script_name);
        
        // Copy script to a location accessible by containers
        let script_content = fs::read_to_string(script_path).await
            .context("Failed to read Parmanode script")?;
        
        // Create a wrapper script that runs in Alpine
        let wrapper_script = format!(
            r#"#!/bin/sh
set -e
{}
"#,
            script_content
        );
        
        // Write wrapper to temp location
        let temp_script = format!("/tmp/parmanode-{}.sh", script_name);
        fs::write(&temp_script, wrapper_script).await
            .context("Failed to write wrapper script")?;
        
        // Make executable
        Command::new("chmod")
            .arg("+x")
            .arg(&temp_script)
            .output()
            .context("Failed to make script executable")?;
        
        // Run script in a temporary Alpine container
        let output = Command::new("podman")
            .arg("run")
            .arg("--rm")
            .arg("--volume")
            .arg(format!("{}:/script.sh:ro", temp_script))
            .arg("alpine:latest")
            .arg("sh")
            .arg("/script.sh")
            .output()
            .context("Failed to execute Parmanode script in container")?;
        
        if !output.status.success() {
            let stderr = String::from_utf8_lossy(&output.stderr);
            return Err(anyhow::anyhow!("Parmanode script failed: {}", stderr));
        }
        
        info!("Parmanode script completed successfully");
        Ok(())
    }
    
    /// Install a Parmanode module (runs script and sets up container)
    pub async fn install_module(&self, module_path: &PathBuf) -> Result<String> {
        // Find the main installation script
        let install_script = module_path.join("install.sh");
        if !install_script.exists() {
            return Err(anyhow::anyhow!("No install.sh found in Parmanode module"));
        }
        
        // Run the installation script
        self.run_script(&install_script).await?;
        
        // Try to convert to app manifest for future management
        let converter = crate::converter::ParmanodeConverter::new();
        match converter.convert_to_manifest(module_path).await {
            Ok(manifest) => {
                info!("Converted Parmanode module to app manifest");
                // TODO: Save manifest for future use
                Ok(manifest.app.id)
            }
            Err(e) => {
                warn!("Failed to convert Parmanode module: {}", e);
                // Return a generic ID
                Ok(format!("parmanode-{}", 
                    module_path.file_name()
                        .and_then(|n| n.to_str())
                        .unwrap_or("module")))
            }
        }
    }
}
