use crate::generated_code;
use rustc::session::Session;
use rustc_parse::lexer::{self, StringReader};
use rustc_span::*;
use syntax::token::{self, TokenKind};

#[derive(Clone)]
pub struct SpanUtils<'a> {
    pub sess: &'a Session,
}

impl<'a> SpanUtils<'a> {
    pub fn new(sess: &'a Session) -> SpanUtils<'a> {
        SpanUtils { sess }
    }

    pub fn make_filename_string(&self, file: &SourceFile) -> String {
        match &file.name {
            FileName::Real(path) if !file.name_was_remapped => {
                if path.is_absolute() {
                    self.sess
                        .source_map()
                        .path_mapping()
                        .map_prefix(path.clone())
                        .0
                        .display()
                        .to_string()
                } else {
                    self.sess.working_dir.0.join(&path).display().to_string()
                }
            }
            // If the file name is already remapped, we assume the user
            // configured it the way they wanted to, so use that directly
            filename => filename.to_string(),
        }
    }

    pub fn snippet(&self, span: Span) -> String {
        match self.sess.source_map().span_to_snippet(span) {
            Ok(s) => s,
            Err(_) => String::new(),
        }
    }

    pub fn retokenise_span(&self, span: Span) -> StringReader<'a> {
        lexer::StringReader::retokenize(&self.sess.parse_sess, span)
    }

    pub fn sub_span_of_token(&self, span: Span, tok: TokenKind) -> Option<Span> {
        let mut toks = self.retokenise_span(span);
        loop {
            let next = toks.next_token();
            if next == token::Eof {
                return None;
            }
            if next == tok {
                return Some(next.span);
            }
        }
    }

    // // Return the name for a macro definition (identifier after first `!`)
    // pub fn span_for_macro_def_name(&self, span: Span) -> Option<Span> {
    //     let mut toks = self.retokenise_span(span);
    //     loop {
    //         let ts = toks.real_token();
    //         if ts == token::Eof {
    //             return None;
    //         }
    //         if ts == token::Not {
    //             let ts = toks.real_token();
    //             if ts.kind.is_ident() {
    //                 return Some(ts.sp);
    //             } else {
    //                 return None;
    //             }
    //         }
    //     }
    // }

    // // Return the name for a macro use (identifier before first `!`).
    // pub fn span_for_macro_use_name(&self, span:Span) -> Option<Span> {
    //     let mut toks = self.retokenise_span(span);
    //     let mut prev = toks.real_token();
    //     loop {
    //         if prev == token::Eof {
    //             return None;
    //         }
    //         let ts = toks.real_token();
    //         if ts == token::Not {
    //             if prev.kind.is_ident() {
    //                 return Some(prev.sp);
    //             } else {
    //                 return None;
    //             }
    //         }
    //         prev = ts;
    //     }
    // }

    /// Return true if the span is generated code, and
    /// it is not a subspan of the root callsite.
    ///
    /// Used to filter out spans of minimal value,
    /// such as references to macro internal variables.
    pub fn filter_generated(&self, span: Span) -> bool {
        if generated_code(span) {
            return true;
        }

        //If the span comes from a fake source_file, filter it.
        !self.sess.source_map().lookup_char_pos(span.lo()).file.is_real_file()
    }
}

macro_rules! filter {
    ($util: expr, $parent: expr) => {
        if $util.filter_generated($parent) {
            return None;
        }
    };
}
