use std::panic::{AssertUnwindSafe, catch_unwind};
use std::path::{Path, PathBuf};

use rustc_ast::{ast, attr, ptr};
use rustc_errors::Diag;
use rustc_parse::parser::Parser as RawParser;
use rustc_parse::{exp, new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
use rustc_span::{Span, sym};
use thin_vec::ThinVec;

use crate::Input;
use crate::parse::session::ParseSess;

pub(crate) type DirectoryOwnership = rustc_expand::module::DirOwnership;
pub(crate) type ModulePathSuccess = rustc_expand::module::ModulePathSuccess;
pub(crate) type ModError<'a> = rustc_expand::module::ModError<'a>;

#[derive(Clone)]
pub(crate) struct Directory {
    pub(crate) path: PathBuf,
    pub(crate) ownership: DirectoryOwnership,
}

/// A parser for Rust source code.
pub(crate) struct Parser<'a> {
    parser: RawParser<'a>,
}

/// A builder for the `Parser`.
#[derive(Default)]
pub(crate) struct ParserBuilder<'a> {
    psess: Option<&'a ParseSess>,
    input: Option<Input>,
}

impl<'a> ParserBuilder<'a> {
    pub(crate) fn input(mut self, input: Input) -> ParserBuilder<'a> {
        self.input = Some(input);
        self
    }

    pub(crate) fn psess(mut self, psess: &'a ParseSess) -> ParserBuilder<'a> {
        self.psess = Some(psess);
        self
    }

    pub(crate) fn build(self) -> Result<Parser<'a>, ParserError> {
        let psess = self.psess.ok_or(ParserError::NoParseSess)?;
        let input = self.input.ok_or(ParserError::NoInput)?;

        let parser = match Self::parser(psess.inner(), input) {
            Ok(p) => p,
            Err(diagnostics) => {
                psess.emit_diagnostics(diagnostics);
                return Err(ParserError::ParserCreationError);
            }
        };

        Ok(Parser { parser })
    }

    fn parser(
        psess: &'a rustc_session::parse::ParseSess,
        input: Input,
    ) -> Result<RawParser<'a>, Vec<Diag<'a>>> {
        match input {
            Input::File(ref file) => new_parser_from_file(psess, file, None),
            Input::Text(text) => new_parser_from_source_str(
                psess,
                rustc_span::FileName::Custom("stdin".to_owned()),
                text,
            ),
        }
    }
}

#[derive(Debug, PartialEq)]
pub(crate) enum ParserError {
    NoParseSess,
    NoInput,
    ParserCreationError,
    ParseError,
    ParsePanicError,
}

impl<'a> Parser<'a> {
    pub(crate) fn submod_path_from_attr(attrs: &[ast::Attribute], path: &Path) -> Option<PathBuf> {
        let path_sym = attr::first_attr_value_str_by_name(attrs, sym::path)?;
        let path_str = path_sym.as_str();

        // On windows, the base path might have the form
        // `\\?\foo\bar` in which case it does not tolerate
        // mixed `/` and `\` separators, so canonicalize
        // `/` to `\`.
        #[cfg(windows)]
        let path_str = path_str.replace("/", "\\");

        Some(path.join(path_str))
    }

    pub(crate) fn parse_file_as_module(
        psess: &'a ParseSess,
        path: &Path,
        span: Span,
    ) -> Result<(ast::AttrVec, ThinVec<ptr::P<ast::Item>>, Span), ParserError> {
        let result = catch_unwind(AssertUnwindSafe(|| {
            let mut parser =
                unwrap_or_emit_fatal(new_parser_from_file(psess.inner(), path, Some(span)));
            match parser.parse_mod(exp!(Eof)) {
                Ok((a, i, spans)) => Some((a, i, spans.inner_span)),
                Err(e) => {
                    e.emit();
                    if psess.can_reset_errors() {
                        psess.reset_errors();
                    }
                    None
                }
            }
        }));
        match result {
            Ok(Some(m)) if !psess.has_errors() => Ok(m),
            Ok(Some(m)) if psess.can_reset_errors() => {
                psess.reset_errors();
                Ok(m)
            }
            Ok(_) => Err(ParserError::ParseError),
            Err(..) if path.exists() => Err(ParserError::ParseError),
            Err(_) => Err(ParserError::ParsePanicError),
        }
    }

    pub(crate) fn parse_crate(
        input: Input,
        psess: &'a ParseSess,
    ) -> Result<ast::Crate, ParserError> {
        let krate = Parser::parse_crate_inner(input, psess)?;
        if !psess.has_errors() {
            return Ok(krate);
        }

        if psess.can_reset_errors() {
            psess.reset_errors();
            return Ok(krate);
        }

        Err(ParserError::ParseError)
    }

    fn parse_crate_inner(input: Input, psess: &'a ParseSess) -> Result<ast::Crate, ParserError> {
        ParserBuilder::default()
            .input(input)
            .psess(psess)
            .build()?
            .parse_crate_mod()
    }

    fn parse_crate_mod(&mut self) -> Result<ast::Crate, ParserError> {
        let mut parser = AssertUnwindSafe(&mut self.parser);
        let err = Err(ParserError::ParsePanicError);
        match catch_unwind(move || parser.parse_crate_mod()) {
            Ok(Ok(k)) => Ok(k),
            Ok(Err(db)) => {
                db.emit();
                err
            }
            Err(_) => err,
        }
    }
}
