//! Support for testing using Docker containers.
//!
//! The [`Container`] type is a builder for configuring a container to run.
//! After you call `launch`, you can use the [`ContainerHandle`] to interact
//! with the running container.
//!
//! Tests using containers must use `#[cargo_test(container_test)]` to disable
//! them unless the CARGO_CONTAINER_TESTS environment variable is set.

use cargo_util::ProcessBuilder;
use std::collections::HashMap;
use std::io::Read;
use std::path::PathBuf;
use std::process::Command;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Mutex;
use tar::Header;

/// A builder for configuring a container to run.
pub struct Container {
    /// The host directory that forms the basis of the Docker image.
    build_context: PathBuf,
    /// Files to copy over to the image.
    files: Vec<MkFile>,
}

/// A handle to a running container.
///
/// You can use this to interact with the container.
pub struct ContainerHandle {
    /// The name of the container.
    name: String,
    /// The IP address of the container.
    ///
    /// NOTE: This is currently unused, but may be useful so I left it in.
    /// This can only be used on Linux. macOS and Windows docker doesn't allow
    /// direct connection to the container.
    pub ip_address: String,
    /// Port mappings of container_port to host_port for ports exposed via EXPOSE.
    pub port_mappings: HashMap<u16, u16>,
}

impl Container {
    pub fn new(context_dir: &str) -> Container {
        assert!(std::env::var_os("CARGO_CONTAINER_TESTS").is_some());
        let mut build_context = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
        build_context.push("containers");
        build_context.push(context_dir);
        Container {
            build_context,
            files: Vec::new(),
        }
    }

    /// Adds a file to be copied into the container.
    pub fn file(mut self, file: MkFile) -> Self {
        self.files.push(file);
        self
    }

    /// Starts the container.
    pub fn launch(mut self) -> ContainerHandle {
        static NEXT_ID: AtomicUsize = AtomicUsize::new(0);

        let id = NEXT_ID.fetch_add(1, Ordering::SeqCst);
        let name = format!("cargo_test_{id}");
        remove_if_exists(&name);
        self.create_container(&name);
        self.copy_files(&name);
        self.start_container(&name);
        let info = self.container_inspect(&name);
        let ip_address = if cfg!(target_os = "linux") {
            info[0]["NetworkSettings"]["IPAddress"]
                .as_str()
                .unwrap()
                .to_string()
        } else {
            // macOS and Windows can't make direct connections to the
            // container. It only works through exposed ports or mapped ports.
            "127.0.0.1".to_string()
        };
        let port_mappings = self.port_mappings(&info);
        self.wait_till_ready(&port_mappings);

        ContainerHandle {
            name,
            ip_address,
            port_mappings,
        }
    }

    fn create_container(&self, name: &str) {
        static BUILD_LOCK: Mutex<()> = Mutex::new(());

        let image_base = self.build_context.file_name().unwrap();
        let image_name = format!("cargo-test-{}", image_base.to_str().unwrap());
        let _lock = BUILD_LOCK
            .lock()
            .map_err(|_| panic!("previous docker build failed, unable to run test"));
        ProcessBuilder::new("docker")
            .args(&["build", "--tag", image_name.as_str()])
            .arg(&self.build_context)
            .exec_with_output()
            .unwrap();

        ProcessBuilder::new("docker")
            .args(&[
                "container",
                "create",
                "--publish-all",
                "--rm",
                "--name",
                name,
            ])
            .arg(image_name)
            .exec_with_output()
            .unwrap();
    }

    fn copy_files(&mut self, name: &str) {
        if self.files.is_empty() {
            return;
        }
        let mut ar = tar::Builder::new(Vec::new());
        ar.sparse(false);
        let files = std::mem::replace(&mut self.files, Vec::new());
        for mut file in files {
            ar.append_data(&mut file.header, &file.path, file.contents.as_slice())
                .unwrap();
        }
        let ar = ar.into_inner().unwrap();
        ProcessBuilder::new("docker")
            .args(&["cp", "-"])
            .arg(format!("{name}:/"))
            .stdin(ar)
            .exec_with_output()
            .unwrap();
    }

    fn start_container(&self, name: &str) {
        ProcessBuilder::new("docker")
            .args(&["container", "start"])
            .arg(name)
            .exec_with_output()
            .unwrap();
    }

    fn container_inspect(&self, name: &str) -> serde_json::Value {
        let output = ProcessBuilder::new("docker")
            .args(&["inspect", name])
            .exec_with_output()
            .unwrap();
        serde_json::from_slice(&output.stdout).unwrap()
    }

    /// Returns the mapping of container_port->host_port for ports that were
    /// exposed with EXPOSE.
    fn port_mappings(&self, info: &serde_json::Value) -> HashMap<u16, u16> {
        info[0]["NetworkSettings"]["Ports"]
            .as_object()
            .unwrap()
            .iter()
            .map(|(key, value)| {
                let key = key
                    .strip_suffix("/tcp")
                    .expect("expected TCP only ports")
                    .parse()
                    .unwrap();
                let values = value.as_array().unwrap();
                let value = values
                    .iter()
                    .find(|value| value["HostIp"].as_str().unwrap() == "0.0.0.0")
                    .expect("expected localhost IP");
                let host_port = value["HostPort"].as_str().unwrap().parse().unwrap();
                (key, host_port)
            })
            .collect()
    }

    fn wait_till_ready(&self, port_mappings: &HashMap<u16, u16>) {
        for port in port_mappings.values() {
            let mut ok = false;
            for _ in 0..30 {
                match std::net::TcpStream::connect(format!("127.0.0.1:{port}")) {
                    Ok(_) => {
                        ok = true;
                        break;
                    }
                    Err(e) => {
                        if e.kind() != std::io::ErrorKind::ConnectionRefused {
                            panic!("unexpected localhost connection error: {e:?}");
                        }
                        std::thread::sleep(std::time::Duration::new(1, 0));
                    }
                }
            }
            if !ok {
                panic!("no listener on localhost port {port}");
            }
        }
    }
}

impl ContainerHandle {
    /// Executes a program inside a running container.
    pub fn exec(&self, args: &[&str]) -> std::process::Output {
        ProcessBuilder::new("docker")
            .args(&["container", "exec", &self.name])
            .args(args)
            .exec_with_output()
            .unwrap()
    }

    /// Returns the contents of a file inside the container.
    pub fn read_file(&self, path: &str) -> String {
        let output = ProcessBuilder::new("docker")
            .args(&["cp", &format!("{}:{}", self.name, path), "-"])
            .exec_with_output()
            .unwrap();
        let mut ar = tar::Archive::new(output.stdout.as_slice());
        let mut entry = ar.entries().unwrap().next().unwrap().unwrap();
        let mut contents = String::new();
        entry.read_to_string(&mut contents).unwrap();
        contents
    }
}

impl Drop for ContainerHandle {
    fn drop(&mut self) {
        // To help with debugging, this will keep the container alive.
        if std::env::var_os("CARGO_CONTAINER_TEST_KEEP").is_some() {
            return;
        }
        remove_if_exists(&self.name);
    }
}

fn remove_if_exists(name: &str) {
    if let Err(e) = Command::new("docker")
        .args(&["container", "rm", "--force", name])
        .output()
    {
        panic!("failed to run docker: {e}");
    }
}

/// Builder for configuring a file to copy into a container.
pub struct MkFile {
    path: String,
    contents: Vec<u8>,
    header: Header,
}

impl MkFile {
    /// Defines a file to add to the container.
    ///
    /// This should be passed to `Container::file`.
    ///
    /// The path is the path inside the container to create the file.
    pub fn path(path: &str) -> MkFile {
        MkFile {
            path: path.to_string(),
            contents: Vec::new(),
            header: Header::new_gnu(),
        }
    }

    pub fn contents(mut self, contents: impl Into<Vec<u8>>) -> Self {
        self.contents = contents.into();
        self.header.set_size(self.contents.len() as u64);
        self
    }

    pub fn mode(mut self, mode: u32) -> Self {
        self.header.set_mode(mode);
        self
    }

    pub fn uid(mut self, uid: u64) -> Self {
        self.header.set_uid(uid);
        self
    }

    pub fn gid(mut self, gid: u64) -> Self {
        self.header.set_gid(gid);
        self
    }
}
