use std::path::{Path, PathBuf};

use bstr::ByteSlice;
use regex::Regex;

#[derive(serde::Deserialize, Debug)]
struct RustcMessage {
    rendered: Option<String>,
    spans: Vec<Span>,
    level: String,
    message: String,
    children: Vec<RustcMessage>,
}

#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub(crate) enum Level {
    Ice = 5,
    Error = 4,
    Warn = 3,
    Help = 2,
    Note = 1,
    /// Only used for "For more information about this error, try `rustc --explain EXXXX`".
    FailureNote = 0,
}

#[derive(Debug)]
pub(crate) struct Message {
    pub(crate) level: Level,
    pub(crate) message: String,
}

/// Information about macro expansion.
#[derive(serde::Deserialize, Debug)]
struct Expansion {
    span: Span,
}

#[derive(serde::Deserialize, Debug)]
struct Span {
    line_start: usize,
    file_name: PathBuf,
    expansion: Option<Box<Expansion>>,
}

impl std::str::FromStr for Level {
    type Err = String;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "ERROR" | "error" => Ok(Self::Error),
            "WARN" | "warning" => Ok(Self::Warn),
            "HELP" | "help" => Ok(Self::Help),
            "NOTE" | "note" => Ok(Self::Note),
            "failure-note" => Ok(Self::FailureNote),
            "error: internal compiler error" => Ok(Self::Ice),
            _ => Err(format!("unknown level `{s}`")),
        }
    }
}

#[derive(Debug)]
pub(crate) struct Diagnostics {
    /// Rendered and concatenated version of all diagnostics.
    /// This is equivalent to non-json diagnostics.
    pub rendered: Vec<u8>,
    /// Per line, a list of messages for that line.
    pub messages: Vec<Vec<Message>>,
    /// Messages not on any line (usually because they are from libstd)
    pub messages_from_unknown_file_or_line: Vec<Message>,
}

impl RustcMessage {
    fn line(&self, file: &Path) -> Option<usize> {
        self.spans.iter().find_map(|span| span.line(file))
    }

    /// Put the message and its children into the line-indexed list.
    fn insert_recursive(
        self,
        file: &Path,
        messages: &mut Vec<Vec<Message>>,
        messages_from_unknown_file_or_line: &mut Vec<Message>,
        line: Option<usize>,
    ) {
        let line = self.line(file).or(line);
        let msg = Message {
            level: self.level.parse().unwrap(),
            message: self.message,
        };
        if let Some(line) = line {
            if messages.len() <= line {
                messages.resize_with(line + 1, Vec::new);
            }
            messages[line].push(msg);
        // All other messages go into the general bin, unless they are specifically of the
        // "aborting due to X previous errors" variety, as we never want to match those. They
        // only count the number of errors and provide no useful information about the tests.
        } else if !(msg.message.starts_with("aborting due to")
            && msg.message.contains("previous error"))
        {
            messages_from_unknown_file_or_line.push(msg);
        }
        for child in self.children {
            child.insert_recursive(file, messages, messages_from_unknown_file_or_line, line)
        }
    }
}

impl Span {
    /// Returns a line number *in the given file*, if possible.
    fn line(&self, file: &Path) -> Option<usize> {
        if self.file_name == file {
            Some(self.line_start)
        } else {
            self.expansion.as_ref()?.span.line(file)
        }
    }
}

pub(crate) fn filter_annotations_from_rendered(rendered: &str) -> std::borrow::Cow<'_, str> {
    let annotations = Regex::new(r" *//(\[[a-z,]+\])?~.*").unwrap();
    annotations.replace_all(rendered, "")
}

pub(crate) fn process(file: &Path, stderr: &[u8]) -> Diagnostics {
    let mut rendered = Vec::new();
    let mut messages = vec![];
    let mut messages_from_unknown_file_or_line = vec![];
    for (line_number, line) in stderr.lines_with_terminator().enumerate() {
        if line.starts_with_str(b"{") {
            match serde_json::from_slice::<RustcMessage>(line) {
                Ok(msg) => {
                    rendered.extend(
                        filter_annotations_from_rendered(msg.rendered.as_ref().unwrap()).as_bytes(),
                    );
                    msg.insert_recursive(
                        file,
                        &mut messages,
                        &mut messages_from_unknown_file_or_line,
                        None,
                    );
                }
                Err(err) => {
                    panic!("failed to parse rustc JSON output at line {line_number}: {err}")
                }
            }
        } else {
            // FIXME: do we want to throw interpreter stderr into a separate file?
            rendered.extend(line);
        }
    }
    Diagnostics {
        rendered,
        messages,
        messages_from_unknown_file_or_line,
    }
}
