use futures::executor::block_on;
use futures::future::Future;
use std::pin::Pin;
use std::sync::{Arc,Mutex};
use std::task::{Context, Poll, Waker};


struct FutureState {
	set: bool,
	waker: Option<Waker>,
}

#[derive(Clone)]
struct MyFuture {
	state: Arc<Mutex<FutureState>>
}

impl MyFuture {
	fn new() -> MyFuture {
		MyFuture{
			state: Arc::new(Mutex::new(FutureState{
				set: false,
				waker: None
			}))
		}
	}

	fn fulfill(&self) {
		let mut state = self.state.lock().unwrap();
		state.set = true;
		if let Some(waker) = state.waker.take() {
			waker.wake()
		}
	}
}

impl Future for MyFuture {
	type Output = ();
	fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
		println!("Polling Future");
		let mut state = self.state.lock().unwrap();
		if state.set {
			println!("Ready");
			Poll::Ready(())
		} else {
			println!("Pending");
			state.waker = Some(cx.waker().clone());
			Poll::Pending
		}
	}
}

async fn hello_world(f1: MyFuture, f2: MyFuture) {
	println!("Enter");
	f1.await;
	println!("Between");
	f2.await;
	println!("Done");
}

fn main() {
	block_on(async {
		let f1 = MyFuture::new();
		let f2 = MyFuture::new();
		let f3 = MyFuture::new();
		let future = hello_world(f1.clone(), f2.clone());

		println!("Before first fulfill");
		f1.fulfill();
		println!("Before second fulfill");
		f2.fulfill();
		println!("Before first await");
		future.await;
		println!("Before second await");
		// future.await;
	});
}