package de.zalando.aruha.nakadi.controller;

import static org.springframework.http.ResponseEntity.ok;
import static org.springframework.http.ResponseEntity.status;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.codahale.metrics.annotation.Timed;

import de.zalando.aruha.nakadi.NakadiException;
import de.zalando.aruha.nakadi.domain.Problem;
import de.zalando.aruha.nakadi.domain.Topic;
import de.zalando.aruha.nakadi.domain.TopicPartition;
import de.zalando.aruha.nakadi.repository.TopicRepository;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;

@RestController
@RequestMapping(value = "/topics")
public class TopicsController {
	private static final Logger LOG = LoggerFactory.getLogger(TopicsController.class);
	@Autowired
	private TopicRepository topicRepository;

	@Timed
	@RequestMapping(value = "/", method = RequestMethod.GET)
	@ApiOperation("Lists all known topics")

	// FIXME: response for 200 does not match reality
	@ApiResponses({ @ApiResponse(code = 200, message = "Returns list of all topics", response = Topic.class),
			@ApiResponse(code = 401, message = "User not authenticated", response = Problem.class),
			@ApiResponse(code = 503, message = "Not available", response = Problem.class) })
	public ResponseEntity<?> listTopics() {
		try {
			return ok().body(topicRepository.listTopics());
		} catch (final NakadiException e) {
			return status(503).body(e.getProblemMessage());
		}
	}

	@Timed
	@RequestMapping(value = "/{topicId}/partitions", method = RequestMethod.GET)
	@ApiOperation("Lists the partitions for the given topic")
	@ApiResponses({ @ApiResponse(code = 200, message = "Returns list of all partitions for the given topic",
			response = TopicPartition.class),
		@ApiResponse(code = 401, message = "User not authenticated", response = Problem.class),
		@ApiResponse(code = 503, message = "Not available", response = Problem.class) })
	public ResponseEntity<?> listPartitions(@PathVariable("topicId") final String topicId) {
		try {
			return ok().body(topicRepository.listPartitions(topicId));
		} catch (final NakadiException e) {
			return status(503).body(e.getProblemMessage());
		}
	}

	@Timed
	@RequestMapping(value = "/{topicId}/partitions/{partitionId}", method = RequestMethod.GET)
	public TopicPartition getPartition(@PathVariable("topicId") final String topicId) {
		throw new UnsupportedOperationException();
	}

	@Timed
	@RequestMapping(value = "/{topicId}/partitions/{partitionId}/events", method = RequestMethod.POST)
	@ApiOperation("Posts an event to the specified partition of this topic.")
	@ApiResponses({ @ApiResponse(code = 201, message = "Event submitted"),
		@ApiResponse(code = 401, message = "User not authenticated", response = Problem.class),
		@ApiResponse(code = 503, message = "Not available", response = Problem.class) })
	public ResponseEntity<?> postEventToPartition(@PathVariable("topicId") final String topicId,
			@PathVariable("partitionId") final String partitionId, @RequestBody final String messagePayload) {
		LOG.trace("Event received: {}, {}, {}", new Object[] { topicId, partitionId, messagePayload });
		try {
			topicRepository.postEvent(topicId, partitionId, messagePayload);
			return ok().build();
		} catch (final NakadiException e) {
			LOG.error("error posting to partition", e);
			return status(500).body(e.getProblemMessage());
		}
	}

	@Timed
	@RequestMapping(value = "/{topicId}/partitions/{partitionId}/events", method = RequestMethod.GET)
	public ResponseEntity<?> readEventFromPartition(@PathVariable("topicId") final String topicId,
			@PathVariable("partitionId") final String partitionId, @RequestBody final String messagePayload) {
		// LOG.trace("Event received: {}, {}, {}", new Object[] { topicId,
		// partitionId, messagePayload });
		topicRepository.readEvent(topicId, partitionId);
		return ok().build();
	}

}

@@ -977,24 +977,64 @@
 iOperation;%0A
+import io.swagger.annotations.ApiParam;%0A
 import io.sw
@@ -2471,16 +2471,85 @@
 titions(
+%0A%09%09%09@ApiParam(name = %22topic%22, value = %22Topic name%22, required = true) 
 @PathVar
@@ -3469,58 +3469,238 @@
 ion(
-@PathVariable(%22topicId%22) final String topicId,%0A%09%09%09
+%0A%09%09%09@ApiParam(name = %22topic%22, value = %22Topic where to send events to%22, required = true) @PathVariable(%22topicId%22) final String topicId,%0A%09%09%09@ApiParam(name = %22partition%22, value = %22Partition where to send events to%22, required = true) 
 @Pat
@@ -3741,33 +3741,36 @@
 ing partitionId,
- 
+%0A%09%09%09
 @RequestBody fin

Add ApiParam annotations to the parameters