// 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

//! Test crate for `ctor_proc_macros`.
//!
//! Because the `ctor` crate is not visible as `::ctor` within
//! itself, we use a separate crate for testing, which can depend on both.
//!
//! And because the proc macros have additional expectations on callers, this is
//! not added to macro_test.

#![cfg(test)]
// Callers are expected to enable `negative_impls`.
// more_qualified_paths is used to make project_pin_type!() simpler to use.
#![feature(negative_impls)]

// pathological shadowed names: shadow important modules that the macros use.
mod std {}
mod ctor {}
mod pin_project {}

#[test]
fn test_derive_default_unit_struct() {
    #[derive(::ctor::CtorFrom_Default)]
    struct Struct;
    unsafe impl ::ctor::RecursivelyPinned for Struct {
        type CtorInitializedFields = Self;
    }
    impl !Unpin for Struct {}

    ::ctor::emplace! {let _p = <Struct as ::ctor::CtorNew<()>>::ctor_new(()); }
}

#[test]
fn test_derive_default_struct() {
    #[derive(::ctor::CtorFrom_Default)]
    struct Struct {
        x: i32,
        y: f32,
    }
    unsafe impl ::ctor::RecursivelyPinned for Struct {
        type CtorInitializedFields = Self;
    }
    impl !Unpin for Struct {}

    ::ctor::emplace! {let p = <Struct as ::ctor::CtorNew<()>>::ctor_new(()); }
    assert_eq!(p.x, 0);
    assert_eq!(p.y, 0.0);
}

#[test]
fn test_derive_default_tuple_struct() {
    #[derive(::ctor::CtorFrom_Default)]
    struct Struct(i32, f32);
    unsafe impl ::ctor::RecursivelyPinned for Struct {
        type CtorInitializedFields = Self;
    }
    impl !Unpin for Struct {}

    ::ctor::emplace! {let p = <Struct as ::ctor::CtorNew<()>>::ctor_new(()); }
    assert_eq!(p.0, 0);
    assert_eq!(p.1, 0.0);
}

#[test]
fn test_recursively_pinned_unit_struct() {
    #[::ctor::recursively_pinned]
    struct S;
    let _ = Box::pin(S).as_mut().project_pin();
    assert_eq!(::std::mem::size_of::<::ctor::project_pin_type!(S)>(), 0);
}

#[test]
fn test_recursively_pinned_fieldless_struct() {
    #[::ctor::recursively_pinned]
    struct S {}
    let _ = Box::pin(S {
        __must_use_ctor_to_initialize: [],  // for tests only!
    })
    .as_mut()
    .project_pin();
    assert_eq!(::std::mem::size_of::<::ctor::project_pin_type!(S)>(), 0);
}

#[test]
fn test_recursively_pinned_fieldless_tuple_struct() {
    #[::ctor::recursively_pinned]
    struct S();
    let _ = Box::pin(S()).as_mut().project_pin();
    assert_eq!(::std::mem::size_of::<::ctor::project_pin_type!(S)>(), 0);
}

#[test]
fn test_recursively_pinned_fieldless_enum() {
    #[::ctor::recursively_pinned]
    enum E {
        A,
    }
    let <::ctor::project_pin_type!(E)>::A = Box::pin(E::A).as_mut().project_pin();
    assert_eq!(::std::mem::size_of::<::ctor::project_pin_type!(E)>(), 0);
}

#[test]
fn test_recursively_pinned_in_module() {
    mod submodule {
        #[::ctor::recursively_pinned]
        pub struct S;
    }
    let _: ::ctor::project_pin_type!(submodule::S) = Box::pin(submodule::S).as_mut().project_pin();
}

#[test]
fn test_recursively_pinned_struct() {
    #[::ctor::recursively_pinned]
    struct S {
        x: i32,
    }
    let _: ::std::pin::Pin<&mut i32> = Box::pin(S {
        x: 42,
        __must_use_ctor_to_initialize: [], // for tests only!
    })
    .as_mut()
    .project_pin()
    .x;
}

#[test]
fn test_recursively_pinned_tuple_struct() {
    #[::ctor::recursively_pinned]
    struct S(i32);
    let _: ::std::pin::Pin<&mut i32> = Box::pin(S(42)).as_mut().project_pin().0;
}

// TODO(b/331688163): remove this workaround.
type Identity<T> = T;

#[test]
fn test_recursively_pinned_enum_struct() {
    #[::ctor::recursively_pinned]
    enum E {
        A { x: i32 },
    }
    match Box::pin(E::A { x: 42 }).as_mut().project_pin() {
        Identity::<::ctor::project_pin_type!(E)>::A { x } => {
            let _: ::std::pin::Pin<&mut i32> = x;
        }
    }
}

#[test]
fn test_recursively_pinned_enum_tuple() {
    #[::ctor::recursively_pinned]
    enum E {
        A(i32),
    }
    match Box::pin(E::A(42)).as_mut().project_pin() {
        Identity::<::ctor::project_pin_type!(E)>::A(x) => {
            let _: ::std::pin::Pin<&mut i32> = x;
        }
    }
}

#[test]
fn test_recursively_pinned_generic() {
    #[::ctor::recursively_pinned]
    struct S<'proj, 'proj_2: 'proj, 'proj_4, T>
    where
        'proj_4: 'proj_2,
    {
        x: T,
        /// 'proj* are not really used, but exist to try to throw a wrench in
        /// the works.
        _phantom: ::std::marker::PhantomData<&'proj &'proj_2 &'proj_4 T>,
    }
    let _: ::std::pin::Pin<&mut i32> = Box::pin(S::<i32> {
        x: 42,
        _phantom: ::std::marker::PhantomData,
        __must_use_ctor_to_initialize: [], // for tests only!
    })
    .as_mut()
    .project_pin()
    .x;
}

#[test]
fn test_recursively_pinned_struct_derive_default() {
    #[::ctor::recursively_pinned]
    #[derive(::ctor::CtorFrom_Default)]
    struct Struct {
        x: i32,
        y: f32,
    }

    ::ctor::emplace! {
        let p = <Struct as ::ctor::CtorNew<()>>::ctor_new(());
    }
    assert_eq!(p.x, 0);
    assert_eq!(p.y, 0.0);
}

/// The same as the previous test, but with the attribute order swapped.
/// This only compiles with macro_attributes_in_derive_output.
#[test]
fn test_derive_default_recursively_pinned_struct() {
    #[derive(::ctor::CtorFrom_Default)]
    #[::ctor::recursively_pinned]
    struct Struct {
        x: i32,
        y: f32,
    }

    ::ctor::emplace! {let p = <Struct as ::ctor::CtorNew<()>>::ctor_new(()); }
    assert_eq!(p.x, 0);
    assert_eq!(p.y, 0.0);
}

#[test]
fn test_recursively_pinned_actually_pinned() {
    #[::ctor::recursively_pinned]
    struct Struct {
        x: i32,
        y: f32,
        pin: ::std::marker::PhantomPinned,
    }

    ::ctor::emplace! {
        let p = ::ctor::ctor!(Struct {
            x: 0,
            y: 0.0,
            pin: ::ctor::PhantomPinnedCtor,
        });
    }
    assert_eq!(p.x, 0);
    assert_eq!(p.y, 0.0);
    // TODO(jeanpierreda): negative compilation test for e.g. `p.x = 1;`
}

// TODO(jeanpierreda): negative compilation tests for invalid parameters to
// #[recursively_pinned]:
// * unknown parameter
// * passing the same parameter twice
// * extra parameters after parameter parsing is complete

// TODO(jeanpierreda): negative compilation tests for Drop / PinnedDrop failures:
// * implemented Drop
// * forgot to implement PinnedDrop
// * implemented PinnedDrop, but forgot to pass in PinnedDrop to
//   `::ctor::recursively_pinned`.

#[test]
fn test_pinned_drop() {
    use ::std::cell::Cell;
    use ::std::rc::Rc;

    #[::ctor::recursively_pinned(PinnedDrop)]
    struct DropStruct(Rc<Cell<bool>>);
    impl ::ctor::PinnedDrop for DropStruct {
        unsafe fn pinned_drop(self: ::std::pin::Pin<&mut Self>) {
            (&*self.project_pin().0).set(true);
        }
    }

    let called_drop = Rc::new(Cell::new(false));
    let _ = DropStruct(called_drop.clone());
    assert!(called_drop.get(), "PinnedDrop::pinned_drop was not called");
}
