#![allow(
    clippy::all,
    clippy::pedantic,
    clippy::nursery,
    clippy::cargo,
    clippy::restriction
)]

use rottlib::arena::Arena;
use rottlib::lexer::TokenizedFile;
use rottlib::parser::Parser;

mod pretty;

// a * * *

/// Expressions to test.
///
/// Add, remove, or edit entries here.
/// Using `(&str, &str)` gives each case a human-readable label.
const TEST_CASES: &[(&str, &str)] = &[
    ("files/P0003_01.uc", "(a + b && c / d ^ e @ f"),
    ("files/P0003_02.uc", "(a]"),
    ("files/P0003_03.uc", "(a\n;"),
];

/// If true, print the parsed expression using Debug formatting.
const PRINT_PARSED_EXPR: bool = false;

/// If true, print diagnostics even when parsing returned a value.
const ALWAYS_PRINT_DIAGNOSTICS: bool = true;

fn main() {
    let arena = Arena::new();

    println!("Running {} expression test case(s)...", TEST_CASES.len());
    println!();

    let mut had_any_problem = false;

    for (idx, (label, source)) in TEST_CASES.iter().enumerate() {
        println!("============================================================");
        println!("Case #{:02}: {}", idx + 1, label);
        println!("Source: {}", source);
        println!("------------------------------------------------------------");

        let tf = TokenizedFile::tokenize(source);

        let mut parser = Parser::new(&tf, &arena);
        let expr = parser.parse_expression();

        println!("parse_expression() returned.");

        if PRINT_PARSED_EXPR {
            println!("Parsed expression:");
            println!("{expr:#?}");
        }

        if parser.diagnostics.is_empty() {
            println!("Diagnostics: none");
        } else {
            had_any_problem = true;
            println!("Diagnostics: {}", parser.diagnostics.len());

            if ALWAYS_PRINT_DIAGNOSTICS {
                let use_colors = false;
                for (k, diag) in parser.diagnostics.iter().enumerate() {
                    let rendered = pretty::render_diagnostic(diag, &tf, Some(label), use_colors);
                    println!("Diagnostic #{}:", k + 1);
                    println!("{rendered}");
                }
            }
        }

        println!();
    }

    println!("============================================================");
    if had_any_problem {
        println!("Done. At least one case had tokenization or parse diagnostics.");
        std::process::exit(1);
    } else {
        println!("Done. All cases completed without diagnostics.");
    }
}