// Path: reactive-lab-gateway/src/main/java/io/reactivex/lab/gateway/clients/BookmarksCommand.java
// public static class Bookmark {
// 
//     private final Map<String, Object> data;
// 
//     Bookmark(Map<String, Object> data) {
//         this.data = data;
//     }
// 
//     public static Bookmark fromJson(String json) {
//         return new Bookmark(SimpleJson.jsonToMap(json));
//     }
// 
//     public int getPosition() {
//         return (int) data.get("position");
//     }
// 
//     public int getVideoId() {
//         return Integer.parseInt(String.valueOf(data.get("videoId")));
//     }
// 
// }
// 
// Path: reactive-lab-gateway/src/main/java/io/reactivex/lab/gateway/clients/PersonalizedCatalogCommand.java
// public static class Video implements ID {
// 
//     private final int id;
// 
//     public Video(int id) {
//         this.id = id;
//     }
// 
//     public int getId() {
//         return id;
//     }
// 
// }
// 
// Path: reactive-lab-gateway/src/main/java/io/reactivex/lab/gateway/common/SimpleJson.java
// public class SimpleJson {
// 
//     private static final SimpleJson INSTANCE = new SimpleJson();
// 
//     private SimpleJson() {
// 
//     }
// 
//     public static Map<String, Object> jsonToMap(String jsonString) {
//         return INSTANCE._jsonToMap(jsonString);
//     }
// 
//     public static String mapToJson(Map<String, ? extends Object> map) {
//         return INSTANCE._mapToJson(map);
//     }
// 
//     private final ObjectMapper objectMapper = new ObjectMapper();
//     private final ObjectReader objectReader = objectMapper.reader(Map.class);
// 
//     private Map<String, Object> _jsonToMap(String jsonString) {
//         try {
//             return objectReader.readValue(jsonString);
//         } catch (IOException e) {
//             throw new RuntimeException("Unable to parse JSON", e);
//         }
//     }
// 
//     private final ObjectWriter objectWriter = objectMapper.writerWithType(Map.class);
// 
//     private String _mapToJson(Map<String, ? extends Object> map) {
//         try {
//             return objectWriter.writeValueAsString(map);
//         } catch (IOException e) {
//             throw new RuntimeException("Unable to write JSON", e);
//         }
//     }
// }


import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixObservableCommand;
import io.netty.buffer.ByteBuf;
import io.reactivex.lab.gateway.clients.BookmarksCommand.Bookmark;
import io.reactivex.lab.gateway.clients.PersonalizedCatalogCommand.Video;
import io.reactivex.lab.gateway.common.SimpleJson;
import io.reactivex.netty.protocol.http.client.HttpClientRequest;
import io.reactivex.netty.protocol.http.sse.ServerSentEvent;
import netflix.ocelli.LoadBalancer;
import netflix.ocelli.rxnetty.HttpClientHolder;
import rx.Observable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
package io.reactivex.lab.gateway.clients;



public class BookmarksCommand extends HystrixObservableCommand<Bookmark> {

    final List<Video> videos;
    private final LoadBalancer<HttpClientHolder<ByteBuf, ServerSentEvent>> loadBalancer;
    final String cacheKey;

    public BookmarksCommand(List<Video> videos, LoadBalancer<HttpClientHolder<ByteBuf, ServerSentEvent>> loadBalancer) {
        super(HystrixCommandGroupKey.Factory.asKey("GetBookmarks"));
        this.videos = videos;
        this.loadBalancer = loadBalancer;
        StringBuilder b = new StringBuilder();
        for (Video v : videos) {
            b.append(v.getId()).append("-");
        }
        this.cacheKey = b.toString();
    }

    @Override
    public Observable<Bookmark> construct() {
        HttpClientRequest<ByteBuf> request = HttpClientRequest.createGet("/bookmarks?" + UrlGenerator.generate("videoId", videos));
// Path: reactive-lab-gateway/src/main/java/io/reactivex/lab/gateway/clients/BookmarksCommand.java
// public static class Bookmark {
// 
//     private final Map<String, Object> data;
// 
//     Bookmark(Map<String, Object> data) {
//         this.data = data;
//     }
// 
//     public static Bookmark fromJson(String json) {
//         return new Bookmark(SimpleJson.jsonToMap(json));
//     }
// 
//     public int getPosition() {
//         return (int) data.get("position");
//     }
// 
//     public int getVideoId() {
//         return Integer.parseInt(String.valueOf(data.get("videoId")));
//     }
// 
// }
// 
// Path: reactive-lab-gateway/src/main/java/io/reactivex/lab/gateway/clients/PersonalizedCatalogCommand.java
// public static class Video implements ID {
// 
//     private final int id;
// 
//     public Video(int id) {
//         this.id = id;
//     }
// 
//     public int getId() {
//         return id;
//     }
// 
// }
// 
// Path: reactive-lab-gateway/src/main/java/io/reactivex/lab/gateway/common/SimpleJson.java
// public class SimpleJson {
// 
//     private static final SimpleJson INSTANCE = new SimpleJson();
// 
//     private SimpleJson() {
// 
//     }
// 
//     public static Map<String, Object> jsonToMap(String jsonString) {
//         return INSTANCE._jsonToMap(jsonString);
//     }
// 
//     public static String mapToJson(Map<String, ? extends Object> map) {
//         return INSTANCE._mapToJson(map);
//     }
// 
//     private final ObjectMapper objectMapper = new ObjectMapper();
//     private final ObjectReader objectReader = objectMapper.reader(Map.class);
// 
//     private Map<String, Object> _jsonToMap(String jsonString) {
//         try {
//             return objectReader.readValue(jsonString);
//         } catch (IOException e) {
//             throw new RuntimeException("Unable to parse JSON", e);
//         }
//     }
// 
//     private final ObjectWriter objectWriter = objectMapper.writerWithType(Map.class);
// 
//     private String _mapToJson(Map<String, ? extends Object> map) {
//         try {
//             return objectWriter.writeValueAsString(map);
//         } catch (IOException e) {
//             throw new RuntimeException("Unable to write JSON", e);
//         }
//     }
// }


// Path: reactive-lab-gateway/src/main/java/io/reactivex/lab/gateway/clients/BookmarksCommand.java
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixObservableCommand;
import io.netty.buffer.ByteBuf;
import io.reactivex.lab.gateway.clients.BookmarksCommand.Bookmark;
import io.reactivex.lab.gateway.clients.PersonalizedCatalogCommand.Video;
import io.reactivex.lab.gateway.common.SimpleJson;
import io.reactivex.netty.protocol.http.client.HttpClientRequest;
import io.reactivex.netty.protocol.http.sse.ServerSentEvent;
import netflix.ocelli.LoadBalancer;
import netflix.ocelli.rxnetty.HttpClientHolder;
import rx.Observable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

package io.reactivex.lab.gateway.clients;



public class BookmarksCommand extends HystrixObservableCommand<Bookmark> {

    final List<Video> videos;
    private final LoadBalancer<HttpClientHolder<ByteBuf, ServerSentEvent>> loadBalancer;
    final String cacheKey;

    public BookmarksCommand(List<Video> videos, LoadBalancer<HttpClientHolder<ByteBuf, ServerSentEvent>> loadBalancer) {
        super(HystrixCommandGroupKey.Factory.asKey("GetBookmarks"));
        this.videos = videos;
        this.loadBalancer = loadBalancer;
        StringBuilder b = new StringBuilder();
        for (Video v : videos) {
            b.append(v.getId()).append("-");
        }
        this.cacheKey = b.toString();
    }

    @Override
    public Observable<Bookmark> construct() {
        HttpClientRequest<ByteBuf> request = HttpClientRequest.createGet("/bookmarks?" + UrlGenerator.generate("videoId", videos));
        return loadBalancer.choose()