//! Do a DNS lookup.
//!
//! This is meant for troubleshooting problems in the VM, when there is no
//! direct hands-on access to its insides.

use std::net::TcpStream;

use serde::{Deserialize, Serialize};

use crate::{
    action::{ActionError, Context},
    action_impl::ActionImpl,
};

/// Upload build artifacts using `rsync` to configured server.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Dns {
    domain: String,
}

impl Dns {
    /// Create a new `Dns` action.
    pub fn new<S: Into<String>>(domain: S) -> Self {
        let mut domain = domain.into();
        if !domain.contains(':') {
            domain.push_str(":80");
        }
        Self { domain }
    }
}

impl ActionImpl for Dns {
    fn execute(&self, context: &mut Context) -> Result<(), ActionError> {
        let res = TcpStream::connect(&self.domain);
        context.runlog().debug(
            crate::runlog::RunLogSource::Plan,
            format!("DNS lookup for {domain}: {res:#?}", domain = self.domain),
        );

        res.map_err(|err| DnsError::Dns(self.domain.clone(), err))?;
        Ok(())
    }
}

/// Errors from Rsync action.
#[derive(Debug, thiserror::Error)]
pub enum DnsError {
    /// DNS lookup failed.
    #[error("DNS lookup failed for {0}")]
    Dns(String, #[source] std::io::Error),
}
