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

#[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;
        }
    };
}
