use vfile::transport::streaming::streaming_transport::StreamingTransport;

use crate::chopper::error::Result;
use crate::input::dir::noop::NoopDirInputFactory;
use crate::input::factory::InputFactory;
use crate::input::location::factory::LocationInputFactory;
use crate::source::source_factory::SourceFactory;

pub struct CustomInputFactoryBuilder<S, EA> {
    user_source_factories: Option<Vec<Box<dyn SourceFactory<S, EA>>>>,
    user_streaming_transports: Option<Vec<Box<dyn StreamingTransport>>>,
}

impl<S, EA> CustomInputFactoryBuilder<S, EA> {
    pub fn new() -> CustomInputFactoryBuilder<S, EA> {
        CustomInputFactoryBuilder {
            user_source_factories: None,
            user_streaming_transports: None,
        }
    }

    pub fn with_user_source_factories(
        mut self,
        user_source_factories: Option<Vec<Box<dyn SourceFactory<S, EA>>>>,
    ) -> Self {
        self.user_source_factories = user_source_factories;
        self
    }

    pub fn with_user_streaming_transports(
        mut self,
        user_streaming_transports: Option<Vec<Box<dyn StreamingTransport>>>,
    ) -> Self {
        self.user_streaming_transports = user_streaming_transports;
        self
    }

    pub fn build(self) -> Result<InputFactory<S, EA>> {
        let source_factories = self.user_source_factories.unwrap_or_default();
        let loc_input_factory =
            LocationInputFactory::new(source_factories, self.user_streaming_transports);
        let dir_input_factory = Box::new(NoopDirInputFactory {});

        InputFactory::new(dir_input_factory, loc_input_factory)
    }
}
