#![allow(warnings)]

mod bindings {
    include!(concat!(env!("OUT_DIR"), "/test.rs"));
}

use std::ffi::CStr;
use std::mem;
use std::os::raw::c_int;

#[allow(unused)]
use bindings::testing::Bar; // This type is generated from module_raw_line.

#[test]
fn test_static_array() {
    let mut test = unsafe { bindings::Test_COUNTDOWN.as_ptr() };
    let expected = unsafe { bindings::Test_countdown() };
    let also_expected = unsafe { bindings::Test_COUNTDOWN_PTR };
    assert!(!test.is_null());
    assert_eq!(also_expected, expected);
    assert_eq!(test, also_expected);

    let mut expected = 10;
    unsafe {
        loop {
            assert_eq!(*test, expected);
            if *test == 0 {
                break;
            }
            test = test.offset(1);
            expected -= 1;
        }
    }
}

#[test]
fn test_static_method() {
    let c_str = unsafe { bindings::Test::name() };
    let name = unsafe { CStr::from_ptr(c_str).to_string_lossy().into_owned() };
    assert_eq!(name, "Test", "Calling a static C++ method works!");
}

#[test]
fn test_constructor() {
    let test = unsafe { bindings::Test::new(5) };
    assert_eq!(test.m_int, 5);
    assert_eq!(test.m_double, 0.0);
}

#[test]
fn test_overload() {
    let test = unsafe { bindings::Test::new1(5.0) };
    assert_eq!(test.m_int, 0);
    assert_eq!(test.m_double, 5.0);
}

#[test]
fn test_bitfields_first() {
    let mut first: bindings::bitfields::First = unsafe { mem::zeroed() };
    assert!(unsafe { first.assert(0, 0, 0) });
    first.set_three_bits_byte_one(2);
    first.set_six_bits_byte_two(42);
    first.set_two_bits_byte_two(1);
    assert!(unsafe { first.assert(2, 42, 1) });
}

#[test]
fn test_bitfields_second() {
    let mut second: bindings::bitfields::Second = unsafe { mem::zeroed() };
    assert!(unsafe { second.assert(0, false) });
    second.set_thirty_one_bits(1337);
    second.set_one_bit(true);
    assert!(unsafe { second.assert(1337, true) });
}

#[test]
fn test_bitfields_third() {
    let mut third: bindings::bitfields::Third = unsafe { mem::zeroed() };
    assert!(unsafe {
        third.assert(0, false, bindings::bitfields::ItemKind::ITEM_KIND_UNO)
    });
    third.set_flags(12345);
    third.set_is_whatever(true);
    third.set_kind(bindings::bitfields::ItemKind::ITEM_KIND_TRES);
    assert!(unsafe {
        third.assert(12345, true, bindings::bitfields::ItemKind::ITEM_KIND_TRES)
    });
}

#[test]
fn test_bitfields_fourth() {
    let mut fourth: bindings::bitfields::Fourth = unsafe { mem::zeroed() };
    assert!(unsafe { fourth.assert(bindings::bitfields::MyEnum::ONE, 0) });

    fourth.set_tag(bindings::bitfields::MyEnum::THREE);
    fourth.set_ptr(0xdeadbeef);
    assert!(unsafe {
        fourth.assert(bindings::bitfields::MyEnum::THREE, 0xdeadbeef)
    });
}

#[test]
fn test_bitfields_date2() {
    let mut date: bindings::bitfields::Date2 = unsafe { mem::zeroed() };
    assert!(unsafe { date.assert(0, 0, 0, 0, 0) });

    date.set_nWeekDay(6); // saturdays are the best
    date.set_nMonthDay(20);
    date.set_nMonth(11);
    date.set_nYear(95);
    date.set_byte(255);
    assert!(unsafe { date.assert(6, 20, 11, 95, 255) });
}

#[test]
fn test_bitfields_fifth() {
    let mut date: bindings::bitfields::Fifth = unsafe { mem::zeroed() };

    assert!(unsafe { date.assert(0, 0, 0, 0, 0) });

    date.byte = 255; // Set this first, to ensure we don't override it.

    date.set_nWeekDay(6); // saturdays are the best
    date.set_nMonthDay(20);
    date.set_nMonth(11);
    date.set_nYear(95);

    assert!(unsafe { date.assert(6, 20, 11, 95, 255) });
}

#[test]
fn test_bitfields_sixth() {
    let mut date: bindings::bitfields::Sixth = unsafe { mem::zeroed() };

    assert!(unsafe { date.assert(0, 0, 0, 0) });

    date.byte = 255;
    date.set_nWeekDay(6); // saturdays are the best
    date.set_nMonthDay(20);
    date.set_nMonth(11);

    assert!(unsafe { date.assert(255, 6, 11, 20) });
}

#[test]
fn test_bitfields_seventh() {
    let mut large: bindings::bitfields::Seventh = unsafe { mem::zeroed() };

    assert!(unsafe { large.assert(false, 0, 0, 0, 0, false, 0) });

    large.set_first_one_bit(true);
    large.set_second_thirty_bits(375028802);
    large.set_third_two_bits(2);
    large.set_fourth_thirty_bits(643472885);
    large.set_fifth_two_bits(3);
    large.set_sixth_one_bit(true);
    large.set_seventh_thirty_bits(1061657575);

    assert!(unsafe {
        large.assert(true, 375028802, 2, 643472885, 3, true, 1061657575)
    });

    assert_eq!(large.first_one_bit(), true);
    assert_eq!(large.second_thirty_bits(), 375028802);
    assert_eq!(large.third_two_bits(), 2);
    assert_eq!(large.fourth_thirty_bits(), 643472885);
    assert_eq!(large.fifth_two_bits(), 3);
    assert_eq!(large.sixth_one_bit(), true);
    assert_eq!(large.seventh_thirty_bits(), 1061657575);
}

#[test]
fn test_bitfield_constructors() {
    use std::mem;
    let mut first = bindings::bitfields::First {
        _bitfield_1: bindings::bitfields::First::new_bitfield_1(1, 2, 3),
    };
    assert!(unsafe { first.assert(1, 2, 3) });

    let mut second = bindings::bitfields::Second {
        _bitfield_1: bindings::bitfields::Second::new_bitfield_1(1337, true),
    };
    assert!(unsafe { second.assert(1337, true) });

    let mut third = bindings::bitfields::Third {
        _bitfield_1: bindings::bitfields::Third::new_bitfield_1(
            42,
            false,
            bindings::bitfields::ItemKind::ITEM_KIND_TRES,
        ),
    };
    assert!(unsafe {
        third.assert(42, false, bindings::bitfields::ItemKind::ITEM_KIND_TRES)
    });
}

impl Drop for bindings::AutoRestoreBool {
    fn drop(&mut self) {
        unsafe { bindings::AutoRestoreBool::destruct(self) }
    }
}

#[test]
fn test_destructors() {
    let mut v = true;

    {
        let auto_restore = unsafe { bindings::AutoRestoreBool::new(&mut v) };
        v = false;
    }

    assert!(v, "Should've been restored when going out of scope");
}

impl Drop for bindings::InheritsFromVirtualDestructor {
    fn drop(&mut self) {
        unsafe {
            bindings::InheritsFromVirtualDestructor_InheritsFromVirtualDestructor_destructor(self)
        }
    }
}

#[test]
fn test_virtual_dtor() {
    unsafe {
        {
            let b = bindings::InheritsFromVirtualDestructor::new();
            // Let it go out of scope.
        }

        assert_eq!(bindings::InheritsFromVirtualDestructor_sDestructorCount, 1);
        assert_eq!(bindings::VirtualDestructor_sDestructorCount, 1);
    }
}

#[test]
fn test_item_rename() {
    assert_eq!(bindings::CONST_VALUE, 3);
    assert_eq!(unsafe { bindings::function_name() }, 4);

    let _foo = bindings::foo {
        member: bindings::bar { foo: 2 },
    };
}
