use crate::bindings::{CsvReaders, CsvWriter, Guest, ReadMap};
use crate::move_money::move_money;

#[allow(warnings)]
mod bindings;
pub mod move_money;

struct Component;

impl Guest for Component {
    fn evaluate(properties: ReadMap, readers: CsvReaders, writer: CsvWriter) -> () {
        let accounts_reader = readers.read_into_string("Account");
        let cost_centres_reader = readers.read_into_string("CostCentre");
        let lines = readers.read_into_string("Line");
        let rules = readers.read_into_string("Rule");

        let use_numeric_accounts = properties
            .get("use_numeric_accounts")
            .map(|param| param == "true")
            .unwrap_or(false);
        let flush_pass = properties
            .get("flush_pass")
            .map(|param| param == "true")
            .unwrap_or(false);

        let mut output_writer = csv::Writer::from_writer(vec![]);
        let result = move_money(
            &mut csv::Reader::from_reader(rules.as_bytes()),
            &mut csv::Reader::from_reader(lines.as_bytes()),
            &mut csv::Reader::from_reader(accounts_reader.as_bytes()),
            &mut csv::Reader::from_reader(cost_centres_reader.as_bytes()),
            &mut output_writer,
            use_numeric_accounts,
            flush_pass,
        );
        match result {
            Ok(_) => {
                let inner = output_writer.into_inner().unwrap();
                let wrapped = String::from_utf8(inner).unwrap();
                writer.write_string(wrapped.as_str());
            }
            Err(e) => {}
        }
    }
}

bindings::export!(Component with_types_in bindings);
