use crate::tree::treenode::TreeNode;

// fl_struct!(SLFreeList, TreeNode);
// fl_impl!(SLFreeList, TreeNode, right, val);

pub struct FooNode<T> {
    nid: usize,
    ptr: *mut FooNode<T>, //The
    val: T,
}

impl<T> FooNode<T> {
    pub fn new(val: T, nid: usize) -> FooNode<T> {
        FooNode {
            nid,
            val,
            ptr: core::ptr::null_mut(),
        }
    }
}

fl_struct!(FooFL, FooNode);
fl_impl!(FooFL, FooNode, ptr, val);

// pub(super) struct FreeList<T> {
//     capacity: usize,
//     len: usize,
//     head: *mut TreeNode<T>,
// }

// impl<T> FreeList<T> {
//     pub(super) fn new(capacity: usize) -> FreeList<T> {
//         let mut fl = FreeList {
//             capacity,
//             len: 0,
//             head: ptr::null_mut(),
//         };
//         fl.alloc(capacity);
//         return fl;
//     }

//     fn alloc(&mut self, size: usize) {
//         let layout = Layout::new::<TreeNode<T>>();

//         let mut count: usize = 0;
//         unsafe {
//             while count < size {
//                 let ptr: *mut TreeNode<T> = alloc(layout) as *mut TreeNode<T>;
//                 if ptr.is_null() {
//                     panic!("memory allocation failed!");
//                 }
//                 self.push_head(ptr);
//                 count += 1;
//             }
//         }
//     }

//     fn push_head(&mut self, ptr: *mut TreeNode<T>) {
//         unsafe {
//             (*ptr).left = ptr::null_mut();
//             if self.head.is_null() {
//                 (*ptr).right = ptr::null_mut();
//             } else {
//                 (*ptr).right = self.head;
//             }
//             self.len += 1;
//             self.head = ptr;
//         }
//     }

//     fn pop_head(&mut self) -> *mut TreeNode<T> {
//         if self.head.is_null() {
//             return ptr::null_mut();
//         }

//         unsafe {
//             let ptr: *mut TreeNode<T> = self.head;
//             self.head = (*ptr).right;
//             (*ptr).right = ptr::null_mut();
//             self.len -= 1;
//             ptr
//         }
//     }

//     pub(super) fn release(&mut self, ptr: *mut TreeNode<T>) -> T {
//         unsafe {
//             let node = ptr::read(ptr);
//             self.push_head(ptr);
//             node.val
//         }
//     }

//     pub(super) fn acquire(&mut self, val: T, nid: usize) -> *mut TreeNode<T> {
//         let mut ptr = self.pop_head();
//         if ptr.is_null() {
//             self.grow();
//             ptr = self.pop_head();
//             if ptr.is_null() {
//                 panic!("alloc failed on acquire");
//             }
//         }
//         let node = TreeNode::new(val, nid);
//         unsafe {
//             ptr::write(ptr, node);
//         }
//         return ptr;
//     }

//     fn grow(&mut self) {
//         if self.capacity == 0 {
//             self.alloc(1);
//         } else {
//             self.alloc(self.capacity);
//             self.capacity *= 2;
//         }
//     }
// }
