use std::io;
use std::path::Path;

use crate::transport::streaming::streaming_transport::StreamingTransport;

#[derive(Clone)]
pub struct HttpTransport;

impl StreamingTransport for HttpTransport {
    fn can_open(&self, path: &Path) -> bool {
        path.starts_with("http://") || path.starts_with("https://")
    }

    fn open(&self, path: &Path) -> io::Result<Box<dyn io::Read + Send>> {
        match ureq::get(path.to_str().unwrap()).call() {
            Ok(response) => Ok(Box::new(response.into_reader())),
            Err(ureq::Error::Status(status, response)) => Err(io::Error::new(
                io::ErrorKind::Other,
                format!(
                    "http error for {} - status: {}; string: {}",
                    path.to_str().unwrap(),
                    status,
                    response.into_string()?
                ),
            )),
            Err(ureq::Error::Transport(transport)) => Err(io::Error::new(
                io::ErrorKind::Other,
                format!(
                    "http transport error for {} - {}",
                    path.to_str().unwrap(),
                    transport
                ),
            )),
        }
    }

    fn box_clone(&self) -> Box<dyn StreamingTransport> {
        Box::new((*self).clone())
    }

    fn name(&self) -> &str {
        "http"
    }
}
