/*
 * Copyright (c) 2011-2016 Pivotal Software Inc, All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.http.server.reactive.bootstrap;

import reactor.core.Loopback;
import reactor.ipc.netty.NettyContext;

import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter;
import org.springframework.util.Assert;

/**
 * @author Stephane Maldini
 */
public class ReactorHttpServer extends HttpServerSupport implements HttpServer, Loopback {

	private ReactorHttpHandlerAdapter reactorHandler;

	private reactor.ipc.netty.http.server.HttpServer reactorServer;

	private NettyContext running;


	@Override
	public void afterPropertiesSet() throws Exception {
		if (getHttpHandlerMap() != null) {
			this.reactorHandler = new ReactorHttpHandlerAdapter(getHttpHandlerMap());
		}
		else {
			Assert.notNull(getHttpHandler());
			this.reactorHandler = new ReactorHttpHandlerAdapter(getHttpHandler());
		}
		this.reactorServer = reactor.ipc.netty.http.server.HttpServer.create(getHost(),
				getPort());
	}


	@Override
	public boolean isRunning() {
		NettyContext running = this.running;
		return running != null && running.channel()
		                                 .isActive();
	}

	@Override
	public Object connectedInput() {
		return reactorServer;
	}

	@Override
	public Object connectedOutput() {
		return reactorServer;
	}

	@Override
	public void start() {
		// TODO: should be made thread-safe (compareAndSet..)
		if (this.running == null) {
			this.running = this.reactorServer.newHandler(reactorHandler).block();
		}
	}

	@Override
	public void stop() {
		NettyContext running = this.running;
		if (running != null) {
			this.running = null;
			running.dispose();
		}
	}
}

@@ -692,16 +692,69 @@
 strap;%0A%0A
+import java.util.concurrent.atomic.AtomicReference;%0A%0A
 import r
@@ -1186,36 +1186,84 @@
 private 
-NettyContext running
+AtomicReference%3CNettyContext%3E nettyContext = new AtomicReference%3C%3E()
 ;%0A%0A%0A%09@Ov
@@ -1627,16 +1627,21 @@
 tpServer
+%0A%09%09%09%09
 .create(
@@ -1650,21 +1650,17 @@
 tHost(),
-%0A%09%09%09%09
+ 
 getPort(
@@ -1720,39 +1720,39 @@
 ettyContext 
-running
+context
  = this.
 running;%0A%09%09r
@@ -1735,31 +1735,42 @@
 text = this.
-running
+nettyContext.get()
 ;%0A%09%09return r
@@ -1768,23 +1768,24 @@
 %09return 
-running
+(context
  != null
@@ -1788,23 +1788,23 @@
 null && 
-running
+context
 .channel
@@ -1809,44 +1809,8 @@
 el()
-%0A%09%09                                 
 .isA
@@ -1816,16 +1816,17 @@
 Active()
+)
 ;%0A%09%7D%0A%0A%09@
@@ -1869,32 +1869,37 @@
 ut() %7B%0A%09%09return 
+this.
 reactorServer;%0A%09
@@ -1956,16 +1956,21 @@
 %09return 
+this.
 reactorS
@@ -2020,80 +2020,35 @@
 %7B%0A%09%09
-// TODO: should be made thread-safe (compareAndSet..)%0A%09%09if (this.running
+if (this.nettyContext.get()
  == 
@@ -2063,26 +2063,33 @@
 %09%09%09this.
-running = 
+nettyContext.set(
 this.rea
@@ -2133,16 +2133,17 @@
 .block()
+)
 ;%0A%09%09%7D%0A%09%7D
@@ -2196,23 +2196,23 @@
 ext 
-running
+context
  = this.
 runn
@@ -2211,23 +2211,44 @@
 his.
-running
+nettyContext.getAndSet(null)
 ;%0A%09%09if (
 runn
@@ -2243,23 +2243,23 @@
 ;%0A%09%09if (
-running
+context
  != null
@@ -2269,39 +2269,15 @@
 %0A%09%09%09
-this.running = null;%0A%09%09%09running
+context
 .dis

Fix TODO in ReactorHttpServer