use std::error::Error;
use std::fs::File;
use std::io::{self, BufRead};
use std::path::Path;
use csv::{QuoteStyle, ReaderBuilder, WriterBuilder};
use serde::de::DeserializeOwned;
use serde::{Serialize};

pub fn read_csv<T>(file_path: &str) -> Result<Vec<T>, Box<dyn Error>>
where
    T: DeserializeOwned,
{
    let file = File::open(file_path)?;
    let mut rdr = ReaderBuilder::new().has_headers(true).from_reader(file);
    let mut records = Vec::new();

    for result in rdr.deserialize() {
        let record= result?;
        records.push(record);
    }

    Ok(records)
}


pub fn write_to_csv<T>(records: Vec<T>, path: &str) -> Result<(), Box<dyn Error>>
where
    T: Serialize,{
    // Create a new CSV writer with the file path
    let file = File::create(path)?;
    let mut wtr = WriterBuilder::new()
        .quote_style(QuoteStyle::Always)
        .from_writer(file);

    // Write the records with headers
    for record in records {
        wtr.serialize(record)?;
    }

    // Ensure all data is written to the file
    wtr.flush()?;
    Ok(())
}

pub fn read_lines<P>(filename: P) -> io::Result<Vec<String>>
where
    P: AsRef<Path>,
{
    let file = File::open(filename)?;
    let buf = io::BufReader::new(file);

    buf.lines().collect()
}