use super::Error;
use super::types::{MemoryMap, Symbol};
use tool_helper::Output;

pub fn write(mut out: Output, memory_map: &MemoryMap) -> Result<Output, Error> {
    const NAME_WIDTH:usize = 64;
    fn print_symbols(out: &mut Output, symbols: &Vec<Symbol>) -> Result<(), Error> {
        for symbol in symbols {
            let mut name = symbol.name.as_str();

            if name.len() > NAME_WIDTH {
                writeln!(out, "\t{}", name)?;
                name = " ";
            }

            writeln!(out, "\t{:<width$} @0x{:X}", name, symbol.adr, width=NAME_WIDTH)?;
        }

        Ok(())
    }

    writeln!(out, "<GLOBAL>:")?;
    print_symbols(&mut out, &memory_map.global)?;
    for section in &memory_map.sections {
        let section_end = section.adr + section.size as u64;

        writeln!(out, "{}: @0x{:X} - 0x{:X}", section.name, section.adr, section_end)?;
        print_symbols(&mut out, &section.symbols)?;
    }

    Ok(out)
}