use crate::atn::ATN;

use crate::tree::RuleNode;
use crate::vocabulary::Vocabulary;

/// Major version of this runtime.
/// Used by generated parser to verify that it is compatible with current version of runtime
pub const VERSION_MAJOR: &str = env!("CARGO_PKG_VERSION_MAJOR");
/// Major version of this runtime.
/// Used by generated parser to verify that it is compatible with current version of runtime
pub const VERSION_MINOR: &str = env!("CARGO_PKG_VERSION_MINOR");

// todo move to compile time check when it will be possible to compare strings in constants
/// Used by generated parser to verify that it is compatible with current version of runtime
pub fn check_version(major: &str, minor: &str) {
    assert!(major == VERSION_MAJOR && minor == VERSION_MINOR,
            "parser is not compatible with current runtime version, please generate parser with the latest version of ANTLR")
}
//todo just a reminder to update version to be inserted in generated parser,
//const _:[();0-!(VERSION_MAJOR == "0" && VERSION_MINOR == "2") as usize] = [];

/// **! Usually generated by ANTLR !**
pub trait Recognizer<'input, 'arena>
where
    'input: 'arena,
{
    type Node: RuleNode<'input, 'arena>;

    fn sempred(
        &mut self,
        _localctx: Option<&'arena Self::Node>,
        _rule_index: i32,
        _action_index: i32,
    ) -> bool
    where
        Self: Sized,
    {
        true
    }

    fn action(
        &mut self,
        _localctx: Option<&'arena Self::Node>,
        _rule_index: i32,
        _action_index: i32,
    ) where
        Self: Sized,
    {
    }

    /// Returns array of rule names.
    /// Used for debugging and error reporting
    fn get_rule_names(&self) -> &[&str] {
        &[]
    }

    fn get_vocabulary(&self) -> &dyn Vocabulary {
        unimplemented!()
    }

    /// Name of the file this recognizer was generated from
    fn get_grammar_file_name(&self) -> &str {
        ""
    }
    fn get_atn(&self) -> &ATN {
        unimplemented!()
    }
}

/// **! Usually generated by ANTLR !**
///
/// Used to make user predicates and actions callable by parser
/// Generated by ANTLR tool from actions and predicated added in grammar file
pub trait Actions<'input, 'arena, P>
where
    'input: 'arena,
    P: Recognizer<'input, 'arena>,
{
    fn sempred(
        _localctx: Option<&'arena P::Node>,
        _rule_index: i32,
        _action_index: i32,
        _recog: &mut P,
    ) -> bool {
        true
    }

    fn action(
        _localctx: Option<&'arena P::Node>,
        _rule_index: i32,
        _action_index: i32,
        _recog: &mut P,
    ) {
    }

    /// Returns array of rule names.
    /// Used for debugging and error reporting
    fn get_rule_names(&self) -> &[&str] {
        &[]
    }
    fn get_vocabulary(&self) -> &dyn Vocabulary {
        unimplemented!()
    }

    /// Name of the file this recognizer was generated from
    fn get_grammar_file_name(&self) -> &str {
        ""
    }
    fn get_atn(&self) -> &ATN {
        unimplemented!()
    }
}

//impl Recognizer for BaseRecognizer {
//    fn get_state(&self) -> i32 {
//        self.state
//    }
//
//    fn set_state(&mut self, _v: i32) {
//        self.state = _v;
//    }
//
//    fn add_error_listener(&mut self, _listener: Box<ErrorListener>) {
//        self.listeners.push(_listener)
//    }
//
//    fn remove_error_listeners(&self) {
//        unimplemented!()
//    }
//
//    fn get_error_listener_dispatch(&self) -> Box<ErrorListener> {
//        unimplemented!()
//    }
//}
//
//pub struct BaseRecognizer {
//    pub listeners: Vec<Box<ErrorListener>>,
//    pub state: i32, //    rule_names: Vec<String>,
//    //    literal_names: Vec<String>,
//    //    symbolic_names: Vec<String>,
//    //    grammar_file_name: String
//}
//
//impl BaseRecognizer {
//    pub fn new_base_recognizer() -> BaseRecognizer {
//        BaseRecognizer {
//            listeners: Vec::new(),
//            state: -1,
//        }
//    }
//
//    fn check_version(&self, _toolVersion: String) {
//        unimplemented!()
//    }
//
//    fn get_token_names(&self) -> Vec<String> {
//        unimplemented!()
//    }
//
//    fn get_rule_index_map(&self) -> Map<i32, String> {
//        unimplemented!()
//    }
//
//    fn get_token_type(&self, _tokenName: String) -> i32 {
//        unimplemented!()
//    }
//
//    fn get_error_header(&self, _e: ANTLRError) -> String {
//        unimplemented!()
//    }
//
//    fn get_token_error_display(&self, _t: &Token) -> String {
//        unimplemented!()
//    }
//}
