use crate::helper::get_image_manager_instance;
use crate::{Handler, Result};
use async_trait::async_trait;
use clap::Args;
use log::LevelFilter;

/// Arguments for our `PullCommand`.
///
/// These arguments are parsed by `clap` and an instance of `PullCommand` containing
/// arguments is provided.
///
/// Example :
///
/// `kaps pull registry.hub.docker.com/library/busybox`
///
/// The `handler` method provided below will be executed.
#[derive(Debug, Args)]
pub struct PullCommand {
    /// The image to pull.
    /// Example : registry.hub.docker.com/library/busybox
    image: String,
    /// By default, the image id will be generated by creating a unique hash for the image digest.
    /// By using --name, you can provide a friendly identifier your image.
    #[clap(long)]
    name: Option<String>,
    /// By default, the command will not pull the image if it was already present.
    /// If `--rm` is provided in arguments, the command will remove the previous image
    /// before pulling the image.
    #[clap(long = "rm")]
    remove_existing: bool,
    /// If set, the command will be executed silently.
    #[clap(long, short)]
    quiet: bool,
}

#[async_trait]
impl Handler for PullCommand {
    async fn handler(&self, logger: &mut env_logger::Builder) -> Result<()> {
        // Change logger behavior and init it
        // If the logger was not initialized, nothing will be displayed into the console.
        if self.quiet {
            logger.filter_level(LevelFilter::Off);
        }
        logger.init();

        let mut im = get_image_manager_instance()?;

        let image_id = im
            .pull(&self.image, &self.remove_existing, &self.name)
            .await?;

        // Here we want to print the image_id
        // so the user can get the output for scripting purposes
        println!("{}", image_id);
        Ok(())
    }
}
