// Copyright 2023-2024 The Regents of the University of California
// Copyright 2024 Cornell University
// released under BSD 3-Clause License
// author: Kevin Laeufer <laeufer@cornell.edu>
use crate::expr::*;
use crate::system::TransitionSystem;
use std::io::Write;

pub fn serialize(
    ctx: &Context,
    writer: &mut impl Write,
    sys: &TransitionSystem,
) -> std::io::Result<()> {
    Serializer::new(ctx, writer).serialize_sys(sys)
}

const VERSION: Option<&str> = option_env!("CARGO_PKG_VERSION");

pub fn serialize_to_str(ctx: &Context, sys: &TransitionSystem) -> String {
    let mut buf = Vec::new();
    serialize(ctx, &mut buf, sys).expect("Failed to write to string!");
    String::from_utf8(buf).expect("Failed to read string we wrote!")
}

struct Serializer<'a, W: Write> {
    #[allow(dead_code)] // TODO: implement serializer which will use the ctx!
    ctx: &'a Context,
    writer: &'a mut W,
}

impl<'a, W: Write> Serializer<'a, W> {
    fn new(ctx: &'a Context, writer: &'a mut W) -> Self {
        Serializer { ctx, writer }
    }

    fn serialize_sys(&mut self, sys: &TransitionSystem) -> std::io::Result<()> {
        writeln!(
            self.writer,
            "; btor2 description of `{}` generated by patron {}",
            sys.name,
            VERSION.unwrap_or_default()
        )?;

        writeln!(self.writer, "; TODO: implement the btor2 serialization!")?;

        Ok(())
    }
}
