#!/usr/bin/env python3
# takes: atoms.tab
# Prints a Rust source file predefined atom values (preregistered by
# emulator::atom during the startup)
import erlangrt.genop as genop


class AddAtom:
    def __init__(self, atom: str, cname: str, atom_id: int):
        self.atom = atom.strip("'")
        self.cname = cname
        self.atom_id = atom_id


def main():
    conf = genop.OTP20()
    tables = genop.OTPTables(conf)

    print("""\
//! Generated by codegen/create_gen_atoms.py
//! Creates array of predefined atoms
//! Config used: {otp} 
#![allow(dead_code)]

use term::immediate;
use term::lterm::LTerm;

""".format(otp=conf.__class__.__name__))

    all_atoms = []
    uniq_atoms = set()
    i = 0

    for a in tables.atom_tab:
        a_name = a.text
        if a_name in uniq_atoms:
            continue
        uniq_atoms.add(a_name)
        all_atoms.append(AddAtom(atom=a_name,
                                 cname=genop.enum_name(a_name),
                                 atom_id=i))
        i += 1

    for a in tables.bif_tab:
        a_name = a.atom
        if a_name in uniq_atoms:
            continue
        uniq_atoms.add(a_name)
        all_atoms.append(AddAtom(atom=a_name,
                                 cname=genop.enum_name(a.cname).upper(),
                                 atom_id=i))
        i += 1

    #
    # Print convenient atom constants
    #
    for a in all_atoms:
        print("pub const {cname}: LTerm = LTerm {{ "
              "value: immediate::make_atom_raw_const({index}) }};"
              "".format(cname=a.cname, index=a.atom_id))

    #
    # Print initialization vector
    #
    print("\npub static ATOM_INIT_NAMES: &'static [&'static str] = &[")
    for a in all_atoms:
        print('  "{atext}", // id={aid}'.format(atext=a.atom, aid=a.atom_id))
    print("];")


if __name__ == "__main__":
    main()
