use vfile::util::buf::previewer::BufPreviewer;

use crate::chopper::error::Result;
use crate::source::csv_input_config::CSVInputConfig;
use crate::source::csv_source::CSVSource;
use crate::source::source::Source;
use crate::source::source_factory::{ChopperSourceFactory, SourceFactory};

#[derive(Clone)]
pub struct CSVSourceFactory {
    pub csv_input_config: CSVInputConfig,
}

impl CSVSourceFactory {
    pub fn new(csv_input_config: CSVInputConfig) -> Self {
        CSVSourceFactory { csv_input_config }
    }
}

impl SourceFactory<Box<dyn Source>, ()> for CSVSourceFactory {
    fn can_create_from_format(&self, format: &str) -> bool {
        format.ends_with(".csv")
    }

    fn can_create_from_previewer(&self, previewer: &BufPreviewer) -> bool {
        // if we were able to get lines of text which were parsed into utf8, then
        // it's probably a fair guess that it's a csv; it's a good idea to have this
        // factory as last one in the list of factories because of generous acceptance
        // criteria
        previewer.lines().is_some()
    }

    fn create_source(&self, preview: BufPreviewer, _: ()) -> Result<Box<dyn Source>> {
        Ok(Box::new(CSVSource::new(preview, &self.csv_input_config)?))
    }

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