class QuietPeriodListener implements Listener {

	protected QuietPeriodListener(long quietPeriodInMS, Listener listenerToWrap, ExceptionHandler exceptionHandler) {
		this.quietPeriodInMS = quietPeriodInMS;
		this.delegate = listenerToWrap;
		this.exceptionHandler = exceptionHandler;
	}

}

class QuietPeriodListenerTest {

	 AssertableExceptionHandler assertableExceptionHandler;
	volatile boolean notified;

	@Test
	public void testQuietPeriodListener() throws Throwable {

		assertableExceptionHandler = new AssertableExceptionHandler();
		Listener originalListener = (path, changeKind) -> {
			assertFalse(notified); // We want this to only be called once
			notified = true;
		};

		Listener quietListener = new QuietPeriodListener(100, originalListener, assertableExceptionHandler);
		
		notified = false;
		quietListener.onChange(null, null);
		assertableExceptionHandler.assertNoErrorInTheBackgroundThread();
		await().atMost(1, SECONDS).until(() -> notified, is(true));
		assertableExceptionHandler.assertNoErrorInTheBackgroundThread();
		
		notified = false;
		quietListener.onChange(null, null);
		quietListener.onChange(null, null);
		assertableExceptionHandler.assertNoErrorInTheBackgroundThread();
		await().atMost(1, SECONDS).until(() -> notified, is(true));
		assertableExceptionHandler.assertNoErrorInTheBackgroundThread();

		
		notified = false;
		quietListener.onChange(null, null);
		assertableExceptionHandler.assertNoErrorInTheBackgroundThread();
		await().atMost(1, SECONDS).until(() -> notified, is(true));
		assertableExceptionHandler.assertNoErrorInTheBackgroundThread();

		Thread.sleep(500);
		
		notified = false;
		quietListener.onChange(null, null);
		assertableExceptionHandler.assertNoErrorInTheBackgroundThread();
		await().atMost(1, SECONDS).until(() -> notified, is(true));
		assertableExceptionHandler.assertNoErrorInTheBackgroundThread();
	}

}