use super::LINT_GROUPS_PRIORITY;
use clippy_utils::diagnostics::span_lint_and_then;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
use rustc_lint::{LateContext, unerased_lint_store};
use rustc_span::{BytePos, Pos as _, SourceFile, Span, SyntaxContext};
use std::ops::Range;
use std::path::Path;
use toml::Spanned;
use toml::de::{DeTable, DeValue};

fn toml_span(range: Range<usize>, file: &SourceFile) -> Span {
    Span::new(
        file.start_pos + BytePos::from_usize(range.start),
        file.start_pos + BytePos::from_usize(range.end),
        SyntaxContext::root(),
        None,
    )
}

struct LintConfig<'a> {
    sp: Range<usize>,
    level: &'a str,
    priority: Option<i64>,
}
impl<'a> LintConfig<'a> {
    fn priority(&self) -> i64 {
        self.priority.unwrap_or(0)
    }

    fn is_implicit(&self) -> bool {
        self.priority.is_none()
    }

    fn parse(value: &'a Spanned<DeValue<'a>>) -> Option<Self> {
        let sp = value.span();
        let (level, priority) = match value.get_ref() {
            DeValue::String(level) => (&**level, None),
            DeValue::Table(tbl) => {
                let level = tbl.get("level")?.get_ref().as_str()?;
                let priority = if let Some(priority) = tbl.get("priority") {
                    let priority = priority.get_ref().as_integer()?;
                    Some(i64::from_str_radix(priority.as_str(), priority.radix()).ok()?)
                } else {
                    None
                };
                (level, priority)
            },
            _ => return None,
        };
        Some(Self { sp, level, priority })
    }
}

fn check_table(cx: &LateContext<'_>, table: &DeTable<'_>, known_groups: &FxHashSet<&str>, file: &SourceFile) {
    let mut lints = Vec::new();
    let mut groups = Vec::new();
    for (name, config) in table {
        if name.get_ref() != "warnings"
            && let Some(config) = LintConfig::parse(config)
        {
            if known_groups.contains(&**name.get_ref()) {
                groups.push((name, config));
            } else {
                lints.push((name, config));
            }
        }
    }

    for (group, group_config) in groups {
        if let Some((conflict, _)) = lints.iter().rfind(|(_, lint_config)| {
            lint_config.priority() == group_config.priority() && lint_config.level != group_config.level
        }) {
            span_lint_and_then(
                cx,
                LINT_GROUPS_PRIORITY,
                toml_span(group.span(), file),
                format!(
                    "lint group `{}` has the same priority ({}) as a lint",
                    group.as_ref(),
                    group_config.priority(),
                ),
                |diag| {
                    let config_span = toml_span(group_config.sp.clone(), file);

                    if group_config.is_implicit() {
                        diag.span_label(config_span, "has an implicit priority of 0");
                    }
                    diag.span_label(toml_span(conflict.span(), file), "has the same priority as this lint");
                    diag.note("the order of the lints in the table is ignored by Cargo");

                    let low_priority = lints
                        .iter()
                        .map(|(_, lint_config)| lint_config.priority().saturating_sub(1))
                        .min()
                        .unwrap_or(-1);
                    diag.span_suggestion_verbose(
                        config_span,
                        format!(
                            "to have lints override the group set `{}` to a lower priority",
                            group.as_ref()
                        ),
                        format!("{{ level = {:?}, priority = {low_priority} }}", group_config.level),
                        Applicability::MaybeIncorrect,
                    );
                },
            );
        }
    }
}

struct LintTbls<'a> {
    rust: Option<&'a DeTable<'a>>,
    clippy: Option<&'a DeTable<'a>>,
}
fn get_lint_tbls<'a>(tbl: &'a DeTable<'a>) -> LintTbls<'a> {
    if let Some(lints) = tbl.get("lints")
        && let Some(lints) = lints.get_ref().as_table()
    {
        let rust = lints.get("rust").and_then(|x| x.get_ref().as_table());
        let clippy = lints.get("clippy").and_then(|x| x.get_ref().as_table());
        LintTbls { rust, clippy }
    } else {
        LintTbls {
            rust: None,
            clippy: None,
        }
    }
}

pub fn check(cx: &LateContext<'_>) {
    if let Ok(file) = cx.tcx.sess.source_map().load_file(Path::new("Cargo.toml"))
        && let Some(src) = file.src.as_deref()
        && let Ok(cargo_toml) = DeTable::parse(src)
    {
        let mut rustc_groups = FxHashSet::default();
        let mut clippy_groups = FxHashSet::default();
        for group in unerased_lint_store(cx.tcx.sess).get_all_group_names() {
            match group.split_once("::") {
                None => {
                    rustc_groups.insert(group);
                },
                Some(("clippy", group)) => {
                    clippy_groups.insert(group);
                },
                _ => {},
            }
        }

        let lints = get_lint_tbls(cargo_toml.get_ref());
        if let Some(lints) = lints.rust {
            check_table(cx, lints, &rustc_groups, &file);
        }
        if let Some(lints) = lints.clippy {
            check_table(cx, lints, &clippy_groups, &file);
        }
        if let Some(tbl) = cargo_toml.get_ref().get("workspace")
            && let Some(tbl) = tbl.get_ref().as_table()
        {
            let lints = get_lint_tbls(tbl);
            if let Some(lints) = lints.rust {
                check_table(cx, lints, &rustc_groups, &file);
            }
            if let Some(lints) = lints.clippy {
                check_table(cx, lints, &clippy_groups, &file);
            }
        }
    }
}
