// Path: cqrs-lib/src/main/java/se/citerus/cqrs/bookstore/event/DomainEvent.java
// public abstract class DomainEvent<T extends GenericId> implements Serializable {
// 
//   public final T aggregateId;
//   public final int version;
//   public final long timestamp;
// 
//   protected DomainEvent(T aggregateId, int version, long timestamp) {
//     this.aggregateId = aggregateId;
//     this.version = version;
//     this.timestamp = timestamp;
//   }
// 
//   @Override
//   public boolean equals(Object o) {
//     return EqualsBuilder.reflectionEquals(this, o);
//   }
// 
//   @Override
//   public int hashCode() {
//     return HashCodeBuilder.reflectionHashCode(this);
//   }
// 
//   @Override
//   public String toString() {
//     return ToStringBuilder.reflectionToString(this, SHORT_PREFIX_STYLE);
//   }
// 
// }
// 
// Path: cqrs-lib/src/main/java/se/citerus/cqrs/bookstore/event/DomainEventStore.java
// public interface DomainEventStore {
// 
//   List<DomainEvent> loadEvents(GenericId id);
// 
//   void save(GenericId id, Class<? extends AggregateRoot> type, List<DomainEvent> events);
// 
//   List<DomainEvent> getAllEvents();
// 
// }
// 
// Path: order-context-parent/order-query/src/main/java/se/citerus/cqrs/bookstore/ordercontext/query/QueryService.java
// public class QueryService {
// 
//   private final OrderListDenormalizer orderListDenormalizer;
//   private final OrdersPerDayAggregator ordersPerDayAggregator;
//   private final ProductCatalogClient productCatalogClient;
// 
//   public QueryService(OrderListDenormalizer orderListDenormalizer,
//                       OrdersPerDayAggregator ordersPerDayAggregator,
//                       ProductCatalogClient productCatalogClient) {
//     this.orderListDenormalizer = orderListDenormalizer;
//     this.ordersPerDayAggregator = ordersPerDayAggregator;
//     this.productCatalogClient = productCatalogClient;
//   }
// 
//   public OrderProjection getOrder(OrderId orderId) {
//     return orderListDenormalizer.get(orderId);
//   }
// 
//   public List<OrderProjection> getOrders() {
//     return orderListDenormalizer.getOrders();
//   }
// 
//   public PublisherContractId findPublisherContract(ProductId productId) {
//     ProductDto product = productCatalogClient.getProduct(productId.id);
//     return new PublisherContractId(product.publisherContractId);
//   }
// 
//   public Map<LocalDate, Integer> getOrdersPerDay() {
//     return ordersPerDayAggregator.getOrdersPerDay();
//   }
// 
// }
// 
// Path: order-context-parent/order-query/src/main/java/se/citerus/cqrs/bookstore/ordercontext/query/orderlist/OrderProjection.java
// public class OrderProjection extends Projection {
// 
//   private final OrderId orderId;
//   private final long orderPlacedTimestamp;
//   private final long orderAmount;
//   private final String customerName;
//   private final List<OrderLineProjection> orderLines;
//   private OrderStatus status;
// 
//   public OrderProjection(@JsonProperty("orderId") OrderId orderId,
//                          @JsonProperty("orderPlacedTimestamp") long orderPlacedTimestamp,
//                          @JsonProperty("customerName") String customerName,
//                          @JsonProperty("orderAmount") long orderAmount,
//                          @JsonProperty("orderLines") List<OrderLineProjection> orderLines,
//                          @JsonProperty("status") OrderStatus status) {
//     this.orderId = orderId;
//     this.orderPlacedTimestamp = orderPlacedTimestamp;
//     this.customerName = customerName;
//     this.orderAmount = orderAmount;
//     this.orderLines = new ArrayList<>(orderLines);
//     this.status = status;
//   }
// 
//   public List<OrderLineProjection> getOrderLines() {
//     return orderLines;
//   }
// 
//   public OrderId getOrderId() {
//     return orderId;
//   }
// 
//   public String getCustomerName() {
//     return customerName;
//   }
// 
//   public long getOrderAmount() {
//     return orderAmount;
//   }
// 
//   public OrderStatus getStatus() {
//     return status;
//   }
// 
//   public void setStatus(OrderStatus status) {
//     this.status = status;
//   }
// 
//   public long getOrderPlacedTimestamp() {
//     return orderPlacedTimestamp;
//   }
// 
// }


import se.citerus.cqrs.bookstore.event.DomainEvent;
import se.citerus.cqrs.bookstore.event.DomainEventStore;
import se.citerus.cqrs.bookstore.ordercontext.query.QueryService;
import se.citerus.cqrs.bookstore.ordercontext.query.orderlist.OrderProjection;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
package se.citerus.cqrs.bookstore.ordercontext.resource;




@Path("query")
@Produces(APPLICATION_JSON)
@Consumes(APPLICATION_JSON)
public class QueryResource {

  private final QueryService queryService;
  private final DomainEventStore eventStore;

  public QueryResource(QueryService queryService, DomainEventStore eventStore) {
    this.queryService = queryService;
    this.eventStore = eventStore;
  }

  @GET
  @Path("events")
  public List<Object[]> getAllEvents() {
    List<DomainEvent> allEvents = eventStore.getAllEvents();
    List<Object[]> eventsToReturn = new LinkedList<>();
    for (DomainEvent event : allEvents) {
      eventsToReturn.add(new Object[]{event.getClass().getSimpleName(), event});
    }
    return eventsToReturn;
  }

  @GET
  @Path("orders")
  public Collection<OrderProjection> getOrders() {
// Path: cqrs-lib/src/main/java/se/citerus/cqrs/bookstore/event/DomainEvent.java
// public abstract class DomainEvent<T extends GenericId> implements Serializable {
// 
//   public final T aggregateId;
//   public final int version;
//   public final long timestamp;
// 
//   protected DomainEvent(T aggregateId, int version, long timestamp) {
//     this.aggregateId = aggregateId;
//     this.version = version;
//     this.timestamp = timestamp;
//   }
// 
//   @Override
//   public boolean equals(Object o) {
//     return EqualsBuilder.reflectionEquals(this, o);
//   }
// 
//   @Override
//   public int hashCode() {
//     return HashCodeBuilder.reflectionHashCode(this);
//   }
// 
//   @Override
//   public String toString() {
//     return ToStringBuilder.reflectionToString(this, SHORT_PREFIX_STYLE);
//   }
// 
// }
// 
// Path: cqrs-lib/src/main/java/se/citerus/cqrs/bookstore/event/DomainEventStore.java
// public interface DomainEventStore {
// 
//   List<DomainEvent> loadEvents(GenericId id);
// 
//   void save(GenericId id, Class<? extends AggregateRoot> type, List<DomainEvent> events);
// 
//   List<DomainEvent> getAllEvents();
// 
// }
// 
// Path: order-context-parent/order-query/src/main/java/se/citerus/cqrs/bookstore/ordercontext/query/QueryService.java
// public class QueryService {
// 
//   private final OrderListDenormalizer orderListDenormalizer;
//   private final OrdersPerDayAggregator ordersPerDayAggregator;
//   private final ProductCatalogClient productCatalogClient;
// 
//   public QueryService(OrderListDenormalizer orderListDenormalizer,
//                       OrdersPerDayAggregator ordersPerDayAggregator,
//                       ProductCatalogClient productCatalogClient) {
//     this.orderListDenormalizer = orderListDenormalizer;
//     this.ordersPerDayAggregator = ordersPerDayAggregator;
//     this.productCatalogClient = productCatalogClient;
//   }
// 
//   public OrderProjection getOrder(OrderId orderId) {
//     return orderListDenormalizer.get(orderId);
//   }
// 
//   public List<OrderProjection> getOrders() {
//     return orderListDenormalizer.getOrders();
//   }
// 
//   public PublisherContractId findPublisherContract(ProductId productId) {
//     ProductDto product = productCatalogClient.getProduct(productId.id);
//     return new PublisherContractId(product.publisherContractId);
//   }
// 
//   public Map<LocalDate, Integer> getOrdersPerDay() {
//     return ordersPerDayAggregator.getOrdersPerDay();
//   }
// 
// }
// 
// Path: order-context-parent/order-query/src/main/java/se/citerus/cqrs/bookstore/ordercontext/query/orderlist/OrderProjection.java
// public class OrderProjection extends Projection {
// 
//   private final OrderId orderId;
//   private final long orderPlacedTimestamp;
//   private final long orderAmount;
//   private final String customerName;
//   private final List<OrderLineProjection> orderLines;
//   private OrderStatus status;
// 
//   public OrderProjection(@JsonProperty("orderId") OrderId orderId,
//                          @JsonProperty("orderPlacedTimestamp") long orderPlacedTimestamp,
//                          @JsonProperty("customerName") String customerName,
//                          @JsonProperty("orderAmount") long orderAmount,
//                          @JsonProperty("orderLines") List<OrderLineProjection> orderLines,
//                          @JsonProperty("status") OrderStatus status) {
//     this.orderId = orderId;
//     this.orderPlacedTimestamp = orderPlacedTimestamp;
//     this.customerName = customerName;
//     this.orderAmount = orderAmount;
//     this.orderLines = new ArrayList<>(orderLines);
//     this.status = status;
//   }
// 
//   public List<OrderLineProjection> getOrderLines() {
//     return orderLines;
//   }
// 
//   public OrderId getOrderId() {
//     return orderId;
//   }
// 
//   public String getCustomerName() {
//     return customerName;
//   }
// 
//   public long getOrderAmount() {
//     return orderAmount;
//   }
// 
//   public OrderStatus getStatus() {
//     return status;
//   }
// 
//   public void setStatus(OrderStatus status) {
//     this.status = status;
//   }
// 
//   public long getOrderPlacedTimestamp() {
//     return orderPlacedTimestamp;
//   }
// 
// }


// Path: order-context-parent/order-query/src/main/java/se/citerus/cqrs/bookstore/ordercontext/resource/QueryResource.java
import se.citerus.cqrs.bookstore.event.DomainEvent;
import se.citerus.cqrs.bookstore.event.DomainEventStore;
import se.citerus.cqrs.bookstore.ordercontext.query.QueryService;
import se.citerus.cqrs.bookstore.ordercontext.query.orderlist.OrderProjection;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;

package se.citerus.cqrs.bookstore.ordercontext.resource;




@Path("query")
@Produces(APPLICATION_JSON)
@Consumes(APPLICATION_JSON)
public class QueryResource {

  private final QueryService queryService;
  private final DomainEventStore eventStore;

  public QueryResource(QueryService queryService, DomainEventStore eventStore) {
    this.queryService = queryService;
    this.eventStore = eventStore;
  }

  @GET
  @Path("events")
  public List<Object[]> getAllEvents() {
    List<DomainEvent> allEvents = eventStore.getAllEvents();
    List<Object[]> eventsToReturn = new LinkedList<>();
    for (DomainEvent event : allEvents) {
      eventsToReturn.add(new Object[]{event.getClass().getSimpleName(), event});
    }
    return eventsToReturn;
  }

  @GET
  @Path("orders")
  public Collection<OrderProjection> getOrders() {
    return queryService.getOrders();