use crate::parser::lexer::tokenize;
use crate::parser::core::driver::{parse_tokens, ParseError};
use crate::parser::ast::Stmt;

pub enum ParseResult {
    Incomplete,
    Error(String),
    Success(Vec<Stmt>),
}

pub fn attempt_parse(source: &str, verbose: bool) -> Result<ParseResult, String> {
    if verbose {
        eprintln!("[attempt_parse] => starting. source.len()={}", source.len());
    }
    let tokens = match tokenize(source, verbose) {
        Ok(t) => t,
        Err(lex_err) => {
            let msg = lex_err.message.to_lowercase();
            if msg.contains("unclosed") || msg.contains("unterminated") {
                if verbose {
                    eprintln!("[attempt_parse] => lex error => incomplete: {}", lex_err.message);
                }
                return Ok(ParseResult::Incomplete);
            }
            if verbose {
                eprintln!("[attempt_parse] => lex error => {}", lex_err.message);
            }
            return Err(lex_err.message);
        }
    };
    if verbose {
        eprintln!("[attempt_parse] => tokens => {:?}", tokens);
    }
    match parse_tokens(&tokens, verbose) {
        Ok(stmts) => {
            if stmts.is_empty() && !source.trim().is_empty() {
                if verbose {
                    eprintln!("[attempt_parse] => stmts.is_empty => Incomplete");
                }
                Ok(ParseResult::Incomplete)
            } else {
                if verbose {
                    eprintln!("[attempt_parse] => parse success => got {} stmts", stmts.len());
                }
                Ok(ParseResult::Success(stmts))
            }
        }
        Err(ParseError { msg, .. }) => {
            let lower = msg.to_lowercase();
            if lower.contains("eof") || lower.contains("unexpected end of input") || lower.contains("unclosed") {
                if verbose {
                    eprintln!("[attempt_parse] => parse error => incomplete: {}", msg);
                }
                Ok(ParseResult::Incomplete)
            } else {
                if verbose {
                    eprintln!("[attempt_parse] => parse error => {}", msg);
                }
                Ok(ParseResult::Error(msg))
            }
        }
    }
}
