Added waitlist/BAL functionality
diff --git a/README.md b/README.md
index 7fee020..97e87a5 100644
--- a/README.md
+++ b/README.md
@@ -124,6 +124,8 @@
                       |---RestAuthenticationFilter.java
                   |---v3.model
                       |---ApiV3.java
+                      |---Waitlist.java
           |---resources
               |---api_v3.proto
+              |---waitlist.proto
       |---test
diff --git a/rest/BookingService.java b/rest/BookingService.java
index 9c46024..b7cc41a 100644
--- a/rest/BookingService.java
+++ b/rest/BookingService.java
@@ -33,7 +33,8 @@
 
 import com.google.protobuf.InvalidProtocolBufferException;
 import com.google.protobuf.util.JsonFormat;
-import com.partner.mapsbooking.v3.model.ApiV3;
+import ext.maps.booking.partner.v3.ApiV3;
+import ext.maps.booking.partner.v3.Waitlist;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
@@ -41,7 +42,7 @@
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 
-/** Booking REST Server for API v3 with authentication. */
+/** Booking REST Server for API v3 with com.partner.mapsbooking.authentication. */
 @Path("/v3")
 public class BookingService {
 
@@ -49,11 +50,11 @@
     return JsonFormat.printer().preservingProtoFieldNames();
   }
 
+  @Path("/HealthCheck")
   @GET
   @Produces(MediaType.TEXT_PLAIN)
   public String checkServer() {
-    // method for testing
-    return "Got it!";
+    return "200";
   }
 
   @Path("/CheckAvailability")
@@ -98,6 +99,58 @@
     throw new UnsupportedOperationException("Not implemented yet");
   }
 
+  @Path("/BatchAvailabilityLookup")
+  @POST
+  @Produces(MediaType.APPLICATION_JSON)
+  @Consumes(MediaType.APPLICATION_JSON)
+  public String batchAvailabilityLookup(String request) throws InvalidProtocolBufferException {
+
+    // use JsonFormat.Parser to convert Json String into protocol buffer
+    ApiV3.BatchAvailabilityLookupRequest.Builder requestBuilder = ApiV3.BatchAvailabilityLookupRequest.newBuilder();
+    JsonFormat.Parser jsonParser = JsonFormat.parser();
+    jsonParser.merge(request, requestBuilder);
+    ApiV3.BatchAvailabilityLookupRequest batchAvailabilityLookupRequest = requestBuilder.build();
+
+    // Unexpected error: throw exception and handle it in BookingExceptionMapper class,
+    // return corresponding response and HTTP code
+    //
+    // Normal path: get response object from the helper function
+    ApiV3.BatchAvailabilityLookupResponse response = performBatchAvailabilityLookup(batchAvailabilityLookupRequest);
+
+    // use JsonFormat to convert protocol buffer to Json
+    String jsonResponse = jsonPrinter().print(response);
+    return jsonResponse;
+  }
+
+  // TODO(partner): Implement this method to perform batch availability lookup
+  private ApiV3.BatchAvailabilityLookupResponse performBatchAvailabilityLookup(ApiV3.BatchAvailabilityLookupRequest request) {
+    //        BatchAvailabilityLookup logic:
+    //        e.g.
+    //        String merchantId = request.getMerchantId();
+    //        List<ApiV3.SlotTime> requestedSlotTimes = request.getSlotTimeList();
+    //
+    //        List<ApiV3.SlotTimeAvailability> slotTimeAvailabilities =
+    //             new ArrayList<SlotTimeAvailability>();
+    //
+    //        loop through all requested slotTimes &
+    //          populate slotTimeAvailabilities with availability status:
+    //        e.g
+    //        for (ApiV3.SlotTime slotTime : requestedSlotTimes) {
+    //            slotTimeAvailabilities.add(SlotTimeAvailability.newBuilder()
+    //              .setSlotTime(slotTime)
+    //              .setAvailable(true)
+    //              .build());
+    //        }
+    //
+    //        ApiV3.BatchAvailabilityLookupResponse response =
+    // ApiV3.BatchAvailabilityLookupResponse.newBuilder()
+    //                .addAllSlotTimeAvailability(slotTimeAvailabilities).build();
+
+    //        return response;
+
+    throw new UnsupportedOperationException("Not implemented yet");
+  }
+
   @Path("/CreateBooking")
   @POST
   @Produces(MediaType.APPLICATION_JSON)
@@ -446,4 +499,167 @@
 
     throw new UnsupportedOperationException("Not implemented yet");
   }
-}
+
+
+  /**
+   * Waitlist Implementation
+   * Proto File - https://developers.google.com/maps-booking/reference/rest-api-v3/waitlists/proto-bundle
+   *
+   * */
+  @Path("/BatchGetWaitEstimates")
+  @POST
+  @Produces(MediaType.APPLICATION_JSON)
+  @Consumes(MediaType.APPLICATION_JSON)
+  public String batchGetWaitEstimates(String request) throws InvalidProtocolBufferException {
+
+    // use JsonFormat.Parser to convert Json String into protocol buffer
+    Waitlist.BatchGetWaitEstimatesRequest.Builder requestBuilder = Waitlist.BatchGetWaitEstimatesRequest.newBuilder();
+    JsonFormat.Parser jsonParser = JsonFormat.parser();
+    jsonParser.merge(request, requestBuilder);
+    Waitlist.BatchGetWaitEstimatesRequest batchGetWaitEstimatesRequest = requestBuilder.build();
+
+    // Unexpected error: throw exception and handle it in BookingExceptionMapper class,
+    // return corresponding response and HTTP code
+    //
+    // Normal path: get response object from the helper function
+    Waitlist.BatchGetWaitEstimatesResponse response = performBatchGetWaitEstimates(batchGetWaitEstimatesRequest);
+
+    // use JsonFormat to convert protocol buffer to Json
+    String jsonResponse = jsonPrinter().print(response);
+    return jsonResponse;
+  }
+
+  // TODO(partner): Implement this method to return wait estimates based on party size
+  private Waitlist.BatchGetWaitEstimatesResponse performBatchGetWaitEstimates(Waitlist.BatchGetWaitEstimatesRequest request) {
+
+    // String merchantId = request.getMerchantId();
+    // String serviceId = request.getServiceId();
+    //
+    // List<Integer> requestedPartySizes = request.getPartySizeList();
+    //
+    // Waitlist.BatchGetWaitEstimatesResponse response = Waitlist.BatchGetWaitEstimatesResponse.newBuilder().setWaitlistStatus(
+    //     WaitlistStatus.OPEN).addAllWaitEstimate(...).build();
+    //
+    // return response;
+
+    throw new UnsupportedOperationException("Not implemented yet");
+  }
+
+  @Path("/CreateWaitlistEntry")
+  @POST
+  @Produces(MediaType.APPLICATION_JSON)
+  @Consumes(MediaType.APPLICATION_JSON)
+  public String createWaitlistEntry(String request) throws InvalidProtocolBufferException {
+
+    // use JsonFormat.Parser to convert Json String into protocol buffer
+    Waitlist.CreateWaitlistEntryRequest.Builder requestBuilder = Waitlist.CreateWaitlistEntryRequest.newBuilder();
+    JsonFormat.Parser jsonParser = JsonFormat.parser();
+    jsonParser.merge(request, requestBuilder);
+    Waitlist.CreateWaitlistEntryRequest createWaitlistEntryRequest = requestBuilder.build();
+
+    // Unexpected error: throw exception and handle it in BookingExceptionMapper class,
+    // return corresponding response and HTTP code
+    //
+    // Normal path: get response object from the helper function
+    Waitlist.CreateWaitlistEntryResponse response = performCreateWaitlistEntry(createWaitlistEntryRequest);
+
+    // use JsonFormat to convert protocol buffer to Json
+    String jsonResponse = jsonPrinter().print(response);
+    return jsonResponse;
+  }
+
+  // TODO(partner): Implement this method to create wait list entry based on request
+  private Waitlist.CreateWaitlistEntryResponse performCreateWaitlistEntry(Waitlist.CreateWaitlistEntryRequest request) {
+
+    // String merchantId = request.getMerchantId();
+    // String serviceId = request.getServiceId();
+    // int partySize = request.getPartySize();
+    //
+    // Waitlist.UserInformation userInformation = request.getUserInformation();
+    // String idempotencyToken = request.getIdempotencyToken();
+
+    // Normal Case -> return a unique waitlist_entry_id e.g
+    // Waitlist.CreateWaitlistEntryResponse response = Waitlist.CreateWaitlistEntryResponse.newBuilder()
+    //     .setWaitlistEntryId(...).build();
+
+    // Business logic error -> set the WaitlistBusinessLogicFailure in the response
+
+    // Waitlist.WaitlistBusinessLogicFailure waitlistBusinessLogicFailure = Waitlist.WaitlistBusinessLogicFailure.newBuilder()
+    //     .setCause(Cause.WAITLIST_FULL).setDescription("").build();
+    //
+    // Waitlist.CreateWaitlistEntryResponse response = Waitlist.CreateWaitlistEntryResponse.newBuilder()
+    //     .setWaitlistBusinessLogicFailure(waitlistBusinessLogicFailure).build();
+    //
+    // return response;
+
+    throw new UnsupportedOperationException("Not implemented yet");
+  }
+
+  @Path("/GetWaitlistEntry")
+  @POST
+  @Produces(MediaType.APPLICATION_JSON)
+  @Consumes(MediaType.APPLICATION_JSON)
+  public String getWaitlistEntry(String request) throws InvalidProtocolBufferException {
+
+    // use JsonFormat.Parser to convert Json String into protocol buffer
+    Waitlist.GetWaitlistEntryRequest.Builder requestBuilder = Waitlist.GetWaitlistEntryRequest.newBuilder();
+    JsonFormat.Parser jsonParser = JsonFormat.parser();
+    jsonParser.merge(request, requestBuilder);
+    Waitlist.GetWaitlistEntryRequest getWaitlistEntryRequest = requestBuilder.build();
+
+    // Unexpected error: throw exception and handle it in BookingExceptionMapper class,
+    // return corresponding response and HTTP code
+    //
+    // Normal path: get response object from the helper function
+    Waitlist.GetWaitlistEntryResponse response = performGetWaitlistEntryRequest(getWaitlistEntryRequest);
+
+    // use JsonFormat to convert protocol buffer to Json
+    String jsonResponse = jsonPrinter().print(response);
+    return jsonResponse;
+  }
+
+  // TODO(partner): Implement this method to return waitlist entry
+  private Waitlist.GetWaitlistEntryResponse performGetWaitlistEntryRequest(Waitlist.GetWaitlistEntryRequest request) {
+
+    // String waitlistEntryId = request.getWaitlistEntryId();
+    //
+    // Waitlist.GetWaitlistEntryResponse response = Waitlist.GetWaitlistEntryResponse.newBuilder()
+    //     .setWaitlistEntry(WaitlistEntry...).build();
+    //
+    // return response;
+
+    throw new UnsupportedOperationException("Not implemented yet");
+  }
+
+  @Path("/DeleteWaitlistEntry")
+  @POST
+  @Produces(MediaType.APPLICATION_JSON)
+  @Consumes(MediaType.APPLICATION_JSON)
+  public String deleteWaitlistEntry(String request) throws InvalidProtocolBufferException {
+
+    // use JsonFormat.Parser to convert Json String into protocol buffer
+    Waitlist.DeleteWaitlistEntryRequest.Builder requestBuilder = Waitlist.DeleteWaitlistEntryRequest.newBuilder();
+    JsonFormat.Parser jsonParser = JsonFormat.parser();
+    jsonParser.merge(request, requestBuilder);
+    Waitlist.DeleteWaitlistEntryRequest deleteWaitlistEntryRequest = requestBuilder.build();
+
+    // Unexpected error: throw exception and handle it in BookingExceptionMapper class,
+    // return corresponding response and HTTP code
+    //
+    // If entry exists, delete it. Otherwise throw 404
+    performDeleteWaitlistEntry(deleteWaitlistEntryRequest);
+
+    return "";
+  }
+
+  // TODO(partner): Implement this method to return waitlist entry
+  private void performDeleteWaitlistEntry(Waitlist.DeleteWaitlistEntryRequest request) {
+
+    // String waitlistEntryId = request.getWaitlistEntryId();
+
+    // If waitlist entry Id exists, delete it
+
+    // If waitlist entry id doesn't exist, return 404
+    // throw new WebApplicationException(400);
+  }
+}
\ No newline at end of file