use std::{path::Path, io::{BufReader, Write}};

use cla::{Lexer, Token};

fn main() {
    eprintln!("Student: Aviv Romem");
    if std::env::args().count() == 2 {
        // Safety: we make sure we have 2 items in the args iterator
        let file_name = std::env::args().skip(1).next().unwrap();
        if file_name.ends_with(".ou") && Path::new(&file_name).exists() {
            let file = std::fs::File::open(&file_name).expect("INVALID FILE");
            let mut buf_reader = BufReader::new(file); // use a buf reader for faster reading
            let mut lexer = Lexer::new(&mut buf_reader); // set up a new lexer instance
            
            // open output file
            let mut output_file = file_name.chars().take(file_name.chars().count() - 3).collect::<String>();
            output_file.push_str(&".tok");
            let mut output = std::fs::File::create(Path::new(&output_file)).expect("Cannot create output file!");
            
            // Loop over the tokens until we get Token::EOF, meaning no more tokens available
            loop {
                let (token, lexeme) = lexer.get_next_token();
                if token == Token::EOF {
                    break;
                }
                // string to print, using `fmt::Debug` derive for easier printing of the token
                let line = format!("Token: {:?}, Lexeme: {}\n", token, lexeme);
                // turn to bytes(UTF-8 by default), write and flush to file
                let as_bytes = line.as_bytes();
                output.write(as_bytes).expect("Failed writing to output file!");
                output.flush().expect("Failed writing to output file!");
            }
        }
        else {
            eprintln!("USAGE: cla <file_name>.ou");
        }
    }
    else {
        eprintln!("USAGE: cla <file_name>.ou");
    }
}
