// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use indexmap::set::IndexSet as HashSet;
use std::fmt::Display;

use crate::types::{make_ident, Namespace, QualifiedName};
use autocxx_parser::{ExternCppType, RustFun, RustPath};
use itertools::Itertools;
use quote::ToTokens;
use syn::{
    parse::Parse,
    punctuated::Punctuated,
    token::{Comma, Unsafe},
    Attribute, FnArg, Ident, ItemConst, ItemEnum, ItemStruct, ItemType, ItemUse, LitBool, LitInt,
    Pat, ReturnType, Type, Visibility,
};

use super::{
    analysis::{
        fun::{
            function_wrapper::{CppFunction, CppFunctionBody, CppFunctionKind},
            ReceiverMutability,
        },
        PointerTreatment,
    },
    convert_error::{ConvertErrorWithContext, ErrorContext},
    ConvertError,
};

#[derive(Copy, Clone, Eq, PartialEq)]
pub(crate) enum TypeKind {
    Pod,    // trivial. Can be moved and copied in Rust.
    NonPod, // has destructor or non-trivial move constructors. Can only hold by UniquePtr
    Abstract, // has pure virtual members - can't even generate UniquePtr.
            // It's possible that the type itself isn't pure virtual, but it inherits from
            // some other type which is pure virtual. Alternatively, maybe we just don't
            // know if the base class is pure virtual because it wasn't on the allowlist,
            // in which case we'll err on the side of caution.
}

/// C++ visibility.
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
pub(crate) enum CppVisibility {
    Public,
    Protected,
    Private,
}

/// Details about a C++ struct.
pub(crate) struct StructDetails {
    pub(crate) vis: CppVisibility,
    pub(crate) item: ItemStruct,
    pub(crate) layout: Option<Layout>,
    pub(crate) has_rvalue_reference_fields: bool,
}

/// Layout of a type, equivalent to the same type in ir/layout.rs in bindgen
#[derive(Clone)]
pub(crate) struct Layout {
    /// The size (in bytes) of this layout.
    pub(crate) size: usize,
    /// The alignment (in bytes) of this layout.
    pub(crate) align: usize,
    /// Whether this layout's members are packed or not.
    pub(crate) packed: bool,
}

impl Parse for Layout {
    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
        let size: LitInt = input.parse()?;
        input.parse::<syn::token::Comma>()?;
        let align: LitInt = input.parse()?;
        input.parse::<syn::token::Comma>()?;
        let packed: LitBool = input.parse()?;
        Ok(Layout {
            size: size.base10_parse().unwrap(),
            align: align.base10_parse().unwrap(),
            packed: packed.value(),
        })
    }
}

#[derive(Clone)]
pub(crate) enum Virtualness {
    None,
    Virtual,
    PureVirtual,
}

#[derive(Clone, Copy)]
pub(crate) enum CastMutability {
    ConstToConst,
    MutToConst,
    MutToMut,
}

/// Indicates that this function (which is synthetic) should
/// be a trait implementation rather than a method or free function.
#[derive(Clone)]
pub(crate) enum TraitSynthesis {
    Cast {
        to_type: QualifiedName,
        mutable: CastMutability,
    },
    AllocUninitialized(QualifiedName),
    FreeUninitialized(QualifiedName),
}

/// Details of a subclass constructor.
/// TODO: zap this; replace with an extra API.
#[derive(Clone)]
pub(crate) struct SubclassConstructorDetails {
    pub(crate) subclass: SubclassName,
    pub(crate) is_trivial: bool,
    /// Implementation of the constructor _itself_ as distinct
    /// from any wrapper function we create to call it.
    pub(crate) cpp_impl: CppFunction,
}

/// Contributions to traits representing C++ superclasses that
/// we may implement as Rust subclasses.
#[derive(Clone)]
pub(crate) struct SuperclassMethod {
    pub(crate) name: Ident,
    pub(crate) receiver: QualifiedName,
    pub(crate) params: Punctuated<FnArg, Comma>,
    pub(crate) param_names: Vec<Pat>,
    pub(crate) ret_type: ReturnType,
    pub(crate) receiver_mutability: ReceiverMutability,
    pub(crate) requires_unsafe: UnsafetyNeeded,
    pub(crate) is_pure_virtual: bool,
}

/// Information about references (as opposed to pointers) to be found
/// within the function signature. This is derived from bindgen annotations
/// which is why it's not within `FuncToConvert::inputs`
#[derive(Default, Clone)]
pub(crate) struct References {
    pub(crate) rvalue_ref_params: HashSet<Ident>,
    pub(crate) ref_params: HashSet<Ident>,
    pub(crate) ref_return: bool,
    pub(crate) rvalue_ref_return: bool,
}

impl References {
    pub(crate) fn new_with_this_and_return_as_reference() -> Self {
        Self {
            ref_return: true,
            ref_params: [make_ident("this")].into_iter().collect(),
            ..Default::default()
        }
    }
    pub(crate) fn param_treatment(&self, param: &Ident) -> PointerTreatment {
        if self.rvalue_ref_params.contains(param) {
            PointerTreatment::RValueReference
        } else if self.ref_params.contains(param) {
            PointerTreatment::Reference
        } else {
            PointerTreatment::Pointer
        }
    }
    pub(crate) fn return_treatment(&self) -> PointerTreatment {
        if self.rvalue_ref_return {
            PointerTreatment::RValueReference
        } else if self.ref_return {
            PointerTreatment::Reference
        } else {
            PointerTreatment::Pointer
        }
    }
}

#[derive(Clone)]
pub(crate) struct TraitImplSignature {
    pub(crate) ty: Type,
    pub(crate) trait_signature: Type,
    /// The trait is 'unsafe' itself
    pub(crate) unsafety: Option<Unsafe>,
}

impl Eq for TraitImplSignature {}

impl PartialEq for TraitImplSignature {
    fn eq(&self, other: &Self) -> bool {
        totokens_equal(&self.unsafety, &other.unsafety)
            && totokens_equal(&self.ty, &other.ty)
            && totokens_equal(&self.trait_signature, &other.trait_signature)
    }
}

fn totokens_to_string<T: ToTokens>(a: &T) -> String {
    a.to_token_stream().to_string()
}

fn totokens_equal<T: ToTokens>(a: &T, b: &T) -> bool {
    totokens_to_string(a) == totokens_to_string(b)
}

fn hash_totokens<T: ToTokens, H: std::hash::Hasher>(a: &T, state: &mut H) {
    use std::hash::Hash;
    totokens_to_string(a).hash(state)
}

impl std::hash::Hash for TraitImplSignature {
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        hash_totokens(&self.ty, state);
        hash_totokens(&self.trait_signature, state);
        hash_totokens(&self.unsafety, state);
    }
}

#[derive(Clone, Debug)]
pub(crate) enum SpecialMemberKind {
    DefaultConstructor,
    CopyConstructor,
    MoveConstructor,
    Destructor,
    AssignmentOperator,
}

impl Display for SpecialMemberKind {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "{}",
            match self {
                SpecialMemberKind::DefaultConstructor => "default constructor",
                SpecialMemberKind::CopyConstructor => "copy constructor",
                SpecialMemberKind::MoveConstructor => "move constructor",
                SpecialMemberKind::Destructor => "destructor",
                SpecialMemberKind::AssignmentOperator => "assignment operator",
            }
        )
    }
}

#[derive(Clone)]
pub(crate) enum Provenance {
    Bindgen,
    SynthesizedOther,
    SynthesizedSubclassConstructor(Box<SubclassConstructorDetails>),
}

/// A C++ function for which we need to generate bindings, but haven't
/// yet analyzed in depth. This is little more than a `ForeignItemFn`
/// broken down into its constituent parts, plus some metadata from the
/// surrounding bindgen parsing context.
///
/// Some parts of the code synthesize additional functions and then
/// pass them through the same pipeline _as if_ they were discovered
/// during normal bindgen parsing. If that happens, they'll create one
/// of these structures, and typically fill in some of the
/// `synthesized_*` members which are not filled in from bindgen.
#[derive(Clone)]
pub(crate) struct FuncToConvert {
    pub(crate) provenance: Provenance,
    pub(crate) ident: Ident,
    pub(crate) doc_attrs: Vec<Attribute>,
    pub(crate) inputs: Punctuated<FnArg, Comma>,
    pub(crate) variadic: bool,
    pub(crate) output: ReturnType,
    pub(crate) vis: Visibility,
    pub(crate) virtualness: Virtualness,
    pub(crate) cpp_vis: CppVisibility,
    pub(crate) special_member: Option<SpecialMemberKind>,
    pub(crate) unused_template_param: bool,
    pub(crate) references: References,
    pub(crate) original_name: Option<String>,
    /// Used for static functions only. For all other functons,
    /// this is figured out from the receiver type in the inputs.
    pub(crate) self_ty: Option<QualifiedName>,
    /// If we wish to use a different 'this' type than the original
    /// method receiver, e.g. because we're making a subclass
    /// constructor, fill it in here.
    pub(crate) synthesized_this_type: Option<QualifiedName>,
    /// If this function should actually belong to a trait.
    pub(crate) add_to_trait: Option<TraitSynthesis>,
    /// If Some, this function didn't really exist in the original
    /// C++ and instead we're synthesizing it.
    pub(crate) synthetic_cpp: Option<(CppFunctionBody, CppFunctionKind)>,
    pub(crate) is_deleted: bool,
}

/// Layers of analysis which may be applied to decorate each API.
/// See description of the purpose of this trait within `Api`.
pub(crate) trait AnalysisPhase {
    type TypedefAnalysis;
    type StructAnalysis;
    type FunAnalysis;
}

/// No analysis has been applied to this API.
pub(crate) struct NullPhase;

impl AnalysisPhase for NullPhase {
    type TypedefAnalysis = ();
    type StructAnalysis = ();
    type FunAnalysis = ();
}

#[derive(Clone)]
pub(crate) enum TypedefKind {
    Use(ItemUse, Box<Type>),
    Type(ItemType),
}

/// Name information for an API. This includes the name by
/// which we know it in Rust, and its C++ name, which may differ.
#[derive(Clone, Hash, PartialEq, Eq)]
pub(crate) struct ApiName {
    pub(crate) name: QualifiedName,
    cpp_name: Option<String>,
}

impl ApiName {
    pub(crate) fn new(ns: &Namespace, id: Ident) -> Self {
        Self::new_from_qualified_name(QualifiedName::new(ns, id))
    }

    pub(crate) fn new_with_cpp_name(ns: &Namespace, id: Ident, cpp_name: Option<String>) -> Self {
        Self {
            name: QualifiedName::new(ns, id),
            cpp_name,
        }
    }

    pub(crate) fn new_from_qualified_name(name: QualifiedName) -> Self {
        Self {
            name,
            cpp_name: None,
        }
    }

    pub(crate) fn new_in_root_namespace(id: Ident) -> Self {
        Self::new(&Namespace::new(), id)
    }

    pub(crate) fn cpp_name(&self) -> String {
        self.cpp_name
            .as_ref()
            .cloned()
            .unwrap_or_else(|| self.name.get_final_item().to_string())
    }

    pub(crate) fn qualified_cpp_name(&self) -> String {
        let cpp_name = self.cpp_name();
        self.name
            .ns_segment_iter()
            .cloned()
            .chain(std::iter::once(cpp_name))
            .join("::")
    }

    pub(crate) fn cpp_name_if_present(&self) -> Option<&String> {
        self.cpp_name.as_ref()
    }
}

impl std::fmt::Debug for ApiName {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.name)?;
        if let Some(cpp_name) = &self.cpp_name {
            write!(f, " (cpp={})", cpp_name)?;
        }
        Ok(())
    }
}

/// A name representing a subclass.
/// This is a simple newtype wrapper which exists such that
/// we can consistently generate the names of the various subsidiary
/// types which are required both in C++ and Rust codegen.
#[derive(Clone, Hash, PartialEq, Eq, Debug)]
pub(crate) struct SubclassName(pub(crate) ApiName);

impl SubclassName {
    pub(crate) fn new(id: Ident) -> Self {
        Self(ApiName::new_in_root_namespace(id))
    }
    pub(crate) fn from_holder_name(id: &Ident) -> Self {
        Self::new(make_ident(id.to_string().strip_suffix("Holder").unwrap()))
    }
    pub(crate) fn id(&self) -> Ident {
        self.0.name.get_final_ident()
    }
    /// Generate the name for the 'Holder' type
    pub(crate) fn holder(&self) -> Ident {
        self.with_suffix("Holder")
    }
    /// Generate the name for the 'Cpp' type
    pub(crate) fn cpp(&self) -> QualifiedName {
        let id = self.with_suffix("Cpp");
        QualifiedName::new(self.0.name.get_namespace(), id)
    }
    pub(crate) fn cpp_remove_ownership(&self) -> Ident {
        self.with_suffix("Cpp_remove_ownership")
    }
    pub(crate) fn remove_ownership(&self) -> Ident {
        self.with_suffix("_remove_ownership")
    }
    fn with_suffix(&self, suffix: &str) -> Ident {
        make_ident(format!("{}{}", self.0.name.get_final_item(), suffix))
    }
    pub(crate) fn get_trait_api_name(sup: &QualifiedName, method_name: &str) -> QualifiedName {
        QualifiedName::new(
            sup.get_namespace(),
            make_ident(format!(
                "{}_{}_trait_item",
                sup.get_final_item(),
                method_name
            )),
        )
    }
    // TODO this and the following should probably include both class name and method name
    pub(crate) fn get_super_fn_name(superclass_namespace: &Namespace, id: &str) -> QualifiedName {
        let id = make_ident(format!("{}_super", id));
        QualifiedName::new(superclass_namespace, id)
    }
    pub(crate) fn get_methods_trait_name(superclass_name: &QualifiedName) -> QualifiedName {
        Self::with_qualified_name_suffix(superclass_name, "methods")
    }
    pub(crate) fn get_supers_trait_name(superclass_name: &QualifiedName) -> QualifiedName {
        Self::with_qualified_name_suffix(superclass_name, "supers")
    }

    fn with_qualified_name_suffix(name: &QualifiedName, suffix: &str) -> QualifiedName {
        let id = make_ident(format!("{}_{}", name.get_final_item(), suffix));
        QualifiedName::new(name.get_namespace(), id)
    }
}

#[derive(strum_macros::Display)]
/// Different types of API we might encounter.
///
/// This type is parameterized over an `ApiAnalysis`. This is any additional
/// information which we wish to apply to our knowledge of our APIs later
/// during analysis phases.
///
/// This is not as high-level as the equivalent types in `cxx` or `bindgen`,
/// because sometimes we pass on the `bindgen` output directly in the
/// Rust codegen output.
///
/// This derives from [strum_macros::Display] because we want to be
/// able to debug-print the enum discriminant without worrying about
/// the fact that their payloads may not be `Debug` or `Display`.
/// (Specifically, allowing `syn` Types to be `Debug` requires
/// enabling syn's `extra-traits` feature which increases compile time.)
pub(crate) enum Api<T: AnalysisPhase> {
    /// A forward declaration, which we mustn't store in a UniquePtr.
    ForwardDeclaration {
        name: ApiName,
        /// If we found a problem parsing this forward declaration, we'll
        /// ephemerally store the error here, as opposed to immediately
        /// converting it to an `IgnoredItem`. That's because the
        /// 'replace_hopeless_typedef_targets' analysis phase needs to spot
        /// cases where there was an error which was _also_ a forward declaration.
        /// That phase will then discard such Api::ForwardDeclarations
        /// and replace them with normal Api::IgnoredItems.
        err: Option<ConvertErrorWithContext>,
    },
    /// We found a typedef to something that we didn't fully understand.
    /// We'll treat it as an opaque unsized type.
    OpaqueTypedef {
        name: ApiName,
        /// Further store whether this was a typedef to a forward declaration.
        /// If so we can't allow it to live in a UniquePtr, just like a regular
        /// Api::ForwardDeclaration.
        forward_declaration: bool,
    },
    /// A synthetic type we've manufactured in order to
    /// concretize some templated C++ type.
    ConcreteType {
        name: ApiName,
        rs_definition: Option<Box<Type>>,
        cpp_definition: String,
    },
    /// A simple note that we want to make a constructor for
    /// a `std::string` on the heap.
    StringConstructor { name: ApiName },
    /// A function. May include some analysis.
    Function {
        name: ApiName,
        fun: Box<FuncToConvert>,
        analysis: T::FunAnalysis,
    },
    /// A constant.
    Const {
        name: ApiName,
        const_item: ItemConst,
    },
    /// A typedef found in the bindgen output which we wish
    /// to pass on in our output
    Typedef {
        name: ApiName,
        item: TypedefKind,
        old_tyname: Option<QualifiedName>,
        analysis: T::TypedefAnalysis,
    },
    /// An enum encountered in the
    /// `bindgen` output.
    Enum { name: ApiName, item: ItemEnum },
    /// A struct encountered in the
    /// `bindgen` output.
    Struct {
        name: ApiName,
        details: Box<StructDetails>,
        analysis: T::StructAnalysis,
    },
    /// A variable-length C integer type (e.g. int, unsigned long).
    CType {
        name: ApiName,
        typename: QualifiedName,
    },
    /// Some item which couldn't be processed by autocxx for some reason.
    /// We will have emitted a warning message about this, but we want
    /// to mark that it's ignored so that we don't attempt to process
    /// dependent items.
    IgnoredItem {
        name: ApiName,
        err: ConvertError,
        ctx: Option<ErrorContext>,
    },
    /// A Rust type which is not a C++ type.
    RustType { name: ApiName, path: RustPath },
    /// A function for the 'extern Rust' block which is not a C++ type.
    RustFn {
        name: ApiName,
        details: RustFun,
        receiver: Option<QualifiedName>,
    },
    /// Some function for the extern "Rust" block.
    RustSubclassFn {
        name: ApiName,
        subclass: SubclassName,
        details: Box<RustSubclassFnDetails>,
    },
    /// A Rust subclass of a C++ class.
    Subclass {
        name: SubclassName,
        superclass: QualifiedName,
    },
    /// Contributions to the traits representing superclass methods that we might
    /// subclass in Rust.
    SubclassTraitItem {
        name: ApiName,
        details: SuperclassMethod,
    },
    /// A type which we shouldn't ourselves generate, but can use in functions
    /// and so-forth by referring to some definition elsewhere.
    ExternCppType {
        name: ApiName,
        details: ExternCppType,
        pod: bool,
    },
}

pub(crate) struct RustSubclassFnDetails {
    pub(crate) params: Punctuated<FnArg, Comma>,
    pub(crate) ret: ReturnType,
    pub(crate) cpp_impl: CppFunction,
    pub(crate) method_name: Ident,
    pub(crate) superclass: QualifiedName,
    pub(crate) receiver_mutability: ReceiverMutability,
    pub(crate) dependencies: Vec<QualifiedName>,
    pub(crate) requires_unsafe: UnsafetyNeeded,
    pub(crate) is_pure_virtual: bool,
}

#[derive(Clone, Debug)]
pub(crate) enum UnsafetyNeeded {
    None,
    JustBridge,
    Always,
}

impl<T: AnalysisPhase> Api<T> {
    pub(crate) fn name_info(&self) -> &ApiName {
        match self {
            Api::ForwardDeclaration { name, .. } => name,
            Api::OpaqueTypedef { name, .. } => name,
            Api::ConcreteType { name, .. } => name,
            Api::StringConstructor { name } => name,
            Api::Function { name, .. } => name,
            Api::Const { name, .. } => name,
            Api::Typedef { name, .. } => name,
            Api::Enum { name, .. } => name,
            Api::Struct { name, .. } => name,
            Api::CType { name, .. } => name,
            Api::IgnoredItem { name, .. } => name,
            Api::RustType { name, .. } => name,
            Api::RustFn { name, .. } => name,
            Api::RustSubclassFn { name, .. } => name,
            Api::Subclass { name, .. } => &name.0,
            Api::SubclassTraitItem { name, .. } => name,
            Api::ExternCppType { name, .. } => name,
        }
    }

    /// The name of this API as used in Rust code.
    /// For types, it's important that this never changes, since
    /// functions or other types may refer to this.
    /// Yet for functions, this may not actually be the name
    /// used in the [cxx::bridge] mod -  see
    /// [Api<FnAnalysis>::cxxbridge_name]
    pub(crate) fn name(&self) -> &QualifiedName {
        &self.name_info().name
    }

    /// The name recorded for use in C++, if and only if
    /// it differs from Rust.
    pub(crate) fn cpp_name(&self) -> &Option<String> {
        &self.name_info().cpp_name
    }

    /// The name for use in C++, whether or not it differs
    /// from Rust.
    pub(crate) fn effective_cpp_name(&self) -> &str {
        self.cpp_name()
            .as_deref()
            .unwrap_or_else(|| self.name().get_final_item())
    }

    /// If this API turns out to have the same QualifiedName as another,
    /// whether it's OK to just discard it?
    pub(crate) fn discard_duplicates(&self) -> bool {
        matches!(self, Api::IgnoredItem { .. })
    }

    pub(crate) fn valid_types(&self) -> Box<dyn Iterator<Item = QualifiedName>> {
        match self {
            Api::Subclass { name, .. } => Box::new(
                vec![
                    self.name().clone(),
                    QualifiedName::new(&Namespace::new(), name.holder()),
                    name.cpp(),
                ]
                .into_iter(),
            ),
            _ => Box::new(std::iter::once(self.name().clone())),
        }
    }
}

impl<T: AnalysisPhase> std::fmt::Debug for Api<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{:?} (kind={})", self.name_info(), self)
    }
}

pub(crate) type UnanalyzedApi = Api<NullPhase>;

impl<T: AnalysisPhase> Api<T> {
    pub(crate) fn typedef_unchanged(
        name: ApiName,
        item: TypedefKind,
        old_tyname: Option<QualifiedName>,
        analysis: T::TypedefAnalysis,
    ) -> Result<Box<dyn Iterator<Item = Api<T>>>, ConvertErrorWithContext>
    where
        T: 'static,
    {
        Ok(Box::new(std::iter::once(Api::Typedef {
            name,
            item,
            old_tyname,
            analysis,
        })))
    }

    pub(crate) fn struct_unchanged(
        name: ApiName,
        details: Box<StructDetails>,
        analysis: T::StructAnalysis,
    ) -> Result<Box<dyn Iterator<Item = Api<T>>>, ConvertErrorWithContext>
    where
        T: 'static,
    {
        Ok(Box::new(std::iter::once(Api::Struct {
            name,
            details,
            analysis,
        })))
    }

    pub(crate) fn fun_unchanged(
        name: ApiName,
        fun: Box<FuncToConvert>,
        analysis: T::FunAnalysis,
    ) -> Result<Box<dyn Iterator<Item = Api<T>>>, ConvertErrorWithContext>
    where
        T: 'static,
    {
        Ok(Box::new(std::iter::once(Api::Function {
            name,
            fun,
            analysis,
        })))
    }

    pub(crate) fn enum_unchanged(
        name: ApiName,
        item: ItemEnum,
    ) -> Result<Box<dyn Iterator<Item = Api<T>>>, ConvertErrorWithContext>
    where
        T: 'static,
    {
        Ok(Box::new(std::iter::once(Api::Enum { name, item })))
    }
}
