import com.sun.grizzly.comet.*;
import com.sun.grizzly.comet.concurrent.DefaultConcurrentCometHandler;
import com.sun.grizzly.http.embed.GrizzlyWebServer;
import com.sun.grizzly.http.embed.Statistics;
import com.sun.grizzly.tcp.http11.GrizzlyAdapter;
import com.sun.grizzly.tcp.http11.GrizzlyRequest;
import com.sun.grizzly.tcp.http11.GrizzlyResponse;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Timestamp;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Main19 {

	private static class CounterHandler implements CometHandler<GrizzlyResponse> {
		private GrizzlyResponse response;

		public void attach(GrizzlyResponse o) {
			this.response = o;
			System.out.println("on attach");			
		}

		private Object obj;

		public void onEvent(CometEvent cometEvent) throws IOException {
			if (cometEvent.getType() == CometEvent.NOTIFY) {
				this.obj = cometEvent.attachment();
				cometEvent.getCometContext().registerAsyncWrite(this);
			} else if (cometEvent.getType() == CometEvent.WRITE) {
				((CometWriter)cometEvent.attachment()).write((obj.toString() + "\n").getBytes("UTF-8"));
			}
		}

		public void onInitialize(CometEvent cometEvent) throws IOException {
			System.out.println("on initialize");
		}

		public void onTerminate(CometEvent cometEvent) throws IOException {
			System.out.println("on terminate");
		}

		public void onInterrupt(CometEvent cometEvent) throws IOException {
			System.out.println("on interrupt");
			cometEvent.getCometContext().removeCometHandler(this);						
		}
	}

	public static void main(String[] args) throws IOException {
		final GrizzlyWebServer gws = new GrizzlyWebServer(4343);
		gws.addAsyncFilter(new CometAsyncFilter());

		gws.getSelectorThread().setAsyncHttpWriteEnabled(true);
		gws.getSelectorThread().setSelectorReadThreadsCount(5);
		gws.getSelectorThread().setCoreThreads(20);
		gws.getSelectorThread().setMaxThreads(100);

		final CometEngine engine = CometEngine.getEngine();
		engine.register("/qwe").setBlockingNotification(true);

		gws.addGrizzlyAdapter(new GrizzlyAdapter() {
			@Override
			public void service(GrizzlyRequest request, GrizzlyResponse response) {
				CounterHandler handler = new CounterHandler();
				handler.attach(response);
				CometContext context = engine.getCometContext("/qwe");
				context.addCometHandler(handler);
			}
		}, new String[]{"/qwe"});

// this is fake thread that will be generating event each second
// evnet is just current time that will be written to client
		Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(new Runnable() {
			public void run() {
				try {
					CometContext ctx = CometEngine.getEngine().getCometContext("/qwe");
					ctx.notify(new Timestamp(System.currentTimeMillis()));
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}, 10, 1, TimeUnit.SECONDS);
		
		gws.start();		
	}
}