// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

//! Support for retrieving Crubit control attributes. These attributes override
//! how Crubit handles a given AST entry.
//!
//! These should never be written directly by users, but rather generated by
//! Crubit itself. (Potentially in a procedural macro.)
#![feature(rustc_private)]
#![deny(rustc::internal)]

extern crate rustc_ast;
extern crate rustc_middle;
extern crate rustc_span;

use anyhow::{bail, ensure, Result};

use rustc_ast::ast::LitKind;
use rustc_ast::ast::{MetaItemKind, NestedMetaItem};
use rustc_middle::ty::TyCtxt;
use rustc_span::def_id::DefId;
use rustc_span::symbol::Symbol;

/// A `#[__crubit::annotate(...)]` attribute.
#[derive(Debug, Default, Clone, PartialEq)]
pub struct CrubitAttr {
    /// The C++ type of this is spelled as so.
    /// For instance,
    /// `#[__crubit::annotate(internal_cc_type="std::basic_string<char>")]`
    pub cc_type: Option<Symbol>,
}

/// Gets the `#[__crubit::annotate(...)]` attribute(s) applied to a definition.
///
/// If the definition has no crubit attributes, then an empty (default)
/// `CrubitAttr` is returned.
pub fn get(tcx: TyCtxt, did: impl Into<DefId>) -> Result<CrubitAttr> {
    // NB: do not make these lazy globals, symbols are per-session and sessions are
    // reset in tests. The resulting test failures are very difficult.
    let crubit_annotate = &[Symbol::intern("__crubit"), Symbol::intern("annotate")];
    let cc_type = Symbol::intern("cc_type");

    let mut crubit_attr = CrubitAttr::default();
    // A quick note: the parsing logic is unfortunate, but such is life. We don't
    // put extra special effort into making the error messages maximally
    // helpful, because they "should never happen": `__crubit::annotate` calls
    // are introduced automatically by Crubit itself, so these errors are only
    // going to be read by Crubit developers when we mess up, not Crubit
    // _users_.
    for attr in tcx.get_attrs_by_path(did.into(), crubit_annotate) {
        let Some(meta) = attr.meta() else {
            bail!("Invalid #[__crubit::annotate(...)] attribute (not a rustc_ast::ast::MetaItem)");
        };
        let MetaItemKind::List(args) = &meta.kind else {
            bail!("Invalid #[__crubit::annotate(...)] attribute (expected __crubit::annotate())");
        };
        for arg in args {
            let NestedMetaItem::MetaItem(arg) = arg else {
                bail!(
                    "Invalid #[__crubit::annotate(...)] attribute (expected nested meta item, not a literal)"
                );
            };
            if arg.path == cc_type {
                let MetaItemKind::NameValue(value) = &arg.kind else {
                    bail!("Invalid #[__crubit::annotate(cc_type=...)] attribute (expected =...)");
                };
                let LitKind::Str(s, _raw) = value.kind else {
                    bail!(
                        "Invalid #[__crubit::annotate(cc_type=...)] attribute (expected =\"...\")"
                    );
                };
                ensure!(
                    crubit_attr.cc_type.is_none(),
                    "Unexpected duplicate #[__crubit::annotate(cc_type=...)]"
                );
                crubit_attr.cc_type = Some(s)
            }
        }
    }
    Ok(crubit_attr)
}

#[cfg(test)]
pub mod tests {
    use super::*;
    use run_compiler_test_support::{find_def_id_by_name, run_compiler_for_testing};

    #[test]
    fn test_missing() {
        let test_src = r#"
                pub struct SomeStruct;
            "#;
        run_compiler_for_testing(test_src, |tcx| {
            let attr = get(tcx, find_def_id_by_name(tcx, "SomeStruct")).unwrap();
            assert_eq!(attr, CrubitAttr::default());
        });
    }

    #[test]
    fn test_empty() {
        let test_src = r#"
                #![feature(register_tool)]
                #![register_tool(__crubit)]
                #[__crubit::annotate()]
                pub struct SomeStruct;
            "#;
        run_compiler_for_testing(test_src, |tcx| {
            let attr = get(tcx, find_def_id_by_name(tcx, "SomeStruct")).unwrap();
            assert_eq!(attr, CrubitAttr::default());
        });
    }

    #[test]
    fn test_cc_type() {
        let test_src = r#"
                #![feature(register_tool)]
                #![register_tool(__crubit)]
                #[__crubit::annotate(cc_type = "A C++ Type")]
                pub struct SomeStruct;
            "#;
        run_compiler_for_testing(test_src, |tcx| {
            let attr = get(tcx, find_def_id_by_name(tcx, "SomeStruct")).unwrap();
            assert_eq!(attr.cc_type.unwrap(), Symbol::intern("A C++ Type"));
        });
    }

    #[test]
    fn test_cc_type_multi() {
        let test_src = r#"
                #![feature(register_tool)]
                #![register_tool(__crubit)]
                #[__crubit::annotate(cc_type = "X", cc_type = "X")]
                pub struct SomeStruct;
            "#;
        run_compiler_for_testing(test_src, |tcx| {
            let attr = get(tcx, find_def_id_by_name(tcx, "SomeStruct"));
            assert!(attr.is_err());
        });
    }
}
