package myfeed.ui;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import lombok.Data;
import lombok.NoArgsConstructor;
import myfeed.AsyncRest;
import myfeed.Rest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import rx.Observable;

/**
 * @author Spencer Gibb
 */
@RestController
public class UiController {
	//public static final ParameterizedTypeReference<PagedResources<FeedItem>> FEED_ITEM_TYPE = new ParameterizedTypeReference<PagedResources<FeedItem>>() {};
	public static final ParameterizedTypeReference<List<FeedItem>> FEED_ITEM_TYPE = new ParameterizedTypeReference<List<FeedItem>>() {};

	@Autowired
	private AsyncRest rest;

	@Autowired
	private Rest syncRest;

	@RequestMapping("/ui/feed/{username}")
	public Feed feed(@PathVariable("username") String username) {
		HashMap<String, Object> map = new HashMap<>();

		return Observable.from(rest.get("http://myfeed-feed/{username}", FEED_ITEM_TYPE, username))
				.map(HttpEntity::getBody)
				.zipWith(Observable.from(rest.getForEntity("http://myfeed-user/@{username}", User.class, username))
						.map(HttpEntity::getBody)
						, (feedItems, user) -> {
					Feed feed = new Feed(feedItems, user);
					return feed;
				})
				.toBlocking()
				.first();
	}

	@Data
	private static class Feed {
		private final List<FeedItem> feed;
		private final User profile;
	}

	@Data
	@NoArgsConstructor
	private static class FeedItem {
		private String id;
		private String userid;
		private String username;
		private String text;
		private Date created;
	}

	@Data
	@NoArgsConstructor
	private static class User {
		private String id;
		private String username;
		private String name;
		private List<String> following = new ArrayList<>();
	}
}

@@ -68,34 +68,8 @@
 te;%0A
-import java.util.HashMap;%0A
 impo
@@ -354,16 +354,64 @@
 Entity;%0A
+import org.springframework.http.ResponseEntity;%0A
 import o
@@ -613,16 +613,48 @@
 vable;%0A%0A
+import static rx.Observable.*;%0A%0A
 /**%0A * @
@@ -1196,76 +1196,47 @@
 %7B%0A%09%09
-HashMap%3CString, Object%3E map = new HashMap%3C%3E();%0A%0A%09%09return Observable.
+Observable%3CList%3CFeedItem%3E%3E feedItems = 
 from
@@ -1338,55 +1338,44 @@
 ody)
-%0A%09%09%09%09.zipWith(Observable.from(rest.getForEntity
+;%0A%0A%09%09Observable%3CFeed%3E feed = getUser
 (%22ht
@@ -1408,20 +1408,8 @@
 e%7D%22,
- User.class,
  use
@@ -1414,20 +1414,17 @@
 sername)
-)%0A%09%09
+%0A
 %09%09%09%09.map
@@ -1453,103 +1453,461 @@
 %09%09%09%09
-%09%09, (feedItems, user) -%3E %7B%0A%09%09%09%09%09Feed feed = new Feed(feedItems, user);%0A%09%09%09%09%09return feed
+.flatMap(user -%3E %7B%0A%09%09%09%09%09// given the user, go get each following user and return the list of usernames%0A%09%09%09%09%09Observable%3CUser%3E u = just(user);%0A%09%09%09%09%09Observable%3CList%3CString%3E%3E following = from(user.getFollowing())%0A%09%09%09%09%09%09%09.flatMap(userid -%3E%0A%09%09%09%09%09%09%09%09%09%09%09getUser(%22http://myfeed-user/users/%7Buserid%7D%22, userid)%0A%09%09%09%09%09%09%09%09%09%09%09%09%09.map(HttpEntity::getBody)%0A%09%09%09%09%09%09%09%09%09%09%09%09%09.map(User::getUsername)%0A%09%09%09%09%09%09%09).toList();%0A%09%09%09%09%09return zip(u, following, feedItems, Feed::new)
 ;%0A%09%09%09%09%7D)
 %0A%09%09%09
@@ -1902,21 +1902,32 @@
 ;%0A%09%09%09%09%7D)
+;%0A
 %0A%09%09
-%09%09
+return feed
 .toBlock
@@ -1935,128 +1935,309 @@
 ng()
-%0A%09%09%09%09.first();%0A%09%7D%0A%0A%09@Data%0A%09private static class Feed %7B%0A%09%09private final List%3CFeedItem%3E feed;%0A%09%09private final User profile
+.first();%0A%09%7D%0A%0A%09private Observable%3CResponseEntity%3CUser%3E%3E getUser(String url, String username) %7B%0A%09%09return from(rest.getForEntity(url, User.class, username));%0A%09%7D%0A%0A%09@Data%0A%09private static class Feed %7B%0A%09%09private final User profile;%0A%09%09private final List%3CString%3E following;%0A%09%09private final List%3CFeedItem%3E feed
 ;%0A%09%7D

add followers to feed data