using GLib;
using Gee;

public class AsyncSearch<G> : Object {
	private bool started = false;
	private bool finished = false;

	private Gee.List<G> buffered_hits = new Gee.ArrayList<G>();

	public signal void hit_found(G hit);

	public signal void done();

	public void start() {
		started = true;
		foreach(weak G hit in buffered_hits)
			hit_found(hit);
		buffered_hits.clear();

		if(finished)
			done();
	}

	public void stop() {
		started = false;
	}

	public void finish() {
		finished = true;
		done();
	}

	public void add_hit(G hit) {
		if(started)
			hit_found(hit);
		else
			buffered_hits.add(hit);
	}
}

class Contact : Object {
	public string name {
		get;
		construct;
	}
}

private class TestCase {
	private static uint nb_contacts = 0;

	private static void contact_found(AsyncSearch<Contact> search, Contact contact) {
		nb_contacts++;
		stdout.printf("Contact found");
	}

	private static void search_done(AsyncSearch<Contact> search) {
		stdout.printf("Total : %u\n", nb_contacts);
	}

	public static int main(string[] args) {
		var search = new AsyncSearch<Contact>();

		search.add_hit(new Contact());
		search.add_hit(new Contact());
		search.finish();

		search.hit_found += contact_found;
		search.done += search_done;
		search.start();

		return 0;
	}
}
