mod codegen;
mod plan;

use shifty::shacl_ir::ShapeIR;

pub use plan::PlanIR;

pub struct GeneratedRust {
    pub root: String,
    pub files: Vec<(String, String)>,
}

impl GeneratedRust {
    pub fn to_single_file(&self) -> String {
        let mut out = String::new();
        out.push_str("// Code generated by shacl-compiler. DO NOT EDIT.\n");
        out.push_str("#![allow(unused_variables)]\n");
        out.push_str("#![allow(dead_code)]\n");
        out.push_str("#![allow(unused_mut)]\n");
        out.push_str("#![allow(unused_imports)]\n");
        out.push_str("#![allow(unused_comparisons)]\n");
        for (_, content) in &self.files {
            out.push_str(content);
            if !content.ends_with('\n') {
                out.push('\n');
            }
            out.push('\n');
        }
        out
    }
}

pub fn generate_rust(ir: &ShapeIR) -> Result<String, String> {
    let plan = PlanIR::from_shape_ir(ir)?;
    generate_rust_from_plan(&plan)
}

pub fn generate_rust_from_plan(plan: &PlanIR) -> Result<String, String> {
    codegen::rust::generate(plan)
}

pub fn generate_rust_modules_from_plan(plan: &PlanIR) -> Result<GeneratedRust, String> {
    codegen::rust::generate_modules(plan)
}
