/*
Copyright 2017 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package api contains validation wrappers over BookingService endpoints.
package api

import (
	"bytes"
	"crypto/tls"
	"crypto/x509"
	"encoding/base64"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"sort"
	"strconv"
	"strings"
	"time"

	"github.com/golang/protobuf/jsonpb"
	"github.com/golang/protobuf/proto"
	"github.com/google/go-cmp/cmp"
	"github.com/maps-booking-v3/utils"

	fpb "github.com/maps-booking-v3/feeds"
	mpb "github.com/maps-booking-v3/v3"
	wpb "github.com/maps-booking-v3/waitlist"
)

const (
	userID    = "0"
	firstName = "Jane"
	lastName  = "Doe"
	telephone = "+1 800-789-7890"
	email     = "test@example.com"
)

// HTTPConnection is a convenience struct for holding connection-related objects.
type HTTPConnection struct {
	client      *http.Client
	credentials string
	marshaler   *jsonpb.Marshaler
	baseURL     string
}

func setupCertConfig(caFile string, fullServerName string) (*tls.Config, error) {
	if caFile == "" {
		return nil, nil
	}
	b, err := ioutil.ReadFile(caFile)
	if err != nil {
		return nil, fmt.Errorf("failed to read root certificates file: %v", err)
	}
	cp := x509.NewCertPool()
	if !cp.AppendCertsFromPEM(b) {
		return nil, errors.New("failed to parse root certificates, please check your roots file (ca_file flag) and try again")
	}
	return &tls.Config{
		RootCAs:    cp,
		ServerName: fullServerName,
	}, nil
}

// InitHTTPConnection creates and returns a new HTTPConnection object
// with a given server address and username/password.
func InitHTTPConnection(serverAddr string, credentialsFile string, caFile string, fullServerName string) (*HTTPConnection, error) {
	// Set up username/password.
	var credentials string
	if credentialsFile != "" {
		data, err := ioutil.ReadFile(credentialsFile)
		if err != nil {
			return nil, err
		}
		credentials = "Basic " + base64.StdEncoding.EncodeToString([]byte(strings.Replace(string(data), "\n", "", -1)))
	}
	config, err := setupCertConfig(caFile, fullServerName)
	if err != nil {
		return nil, err
	}
	protocol := "http"
	if config != nil {
		protocol = "https"
	}
	return &HTTPConnection{
		client: &http.Client{
			Timeout:   10 * time.Second,
			Transport: &http.Transport{TLSClientConfig: config},
		},
		credentials: credentials,
		marshaler:   &jsonpb.Marshaler{OrigName: true},
		baseURL:     protocol + "://" + serverAddr,
	}, nil
}

func (h HTTPConnection) getURL(rpcName string) string {
	if rpcName != "" {
		return h.baseURL + "/v3/" + rpcName
	}
	return h.baseURL
}

// Bookings is a convenience type for a booking array.
type Bookings []*mpb.Booking

func (b Bookings) Len() int {
	return len(b)
}

func (b Bookings) Less(i, j int) bool {
	return b[i].GetBookingId() < b[j].GetBookingId()
}

func (b Bookings) Swap(i, j int) {
	b[i], b[j] = b[j], b[i]
}

// HealthCheck performs a health check.
func HealthCheck(conn *HTTPConnection) error {
	utils.LogFlow("Health Check", "Start")
	defer utils.LogFlow("Health Check", "End")

	httpReq, err := http.NewRequest("GET", conn.getURL("HealthCheck"), nil)
	httpReq.Header.Set("Authorization", conn.credentials)

	// See if we get a response.
	resp, err := conn.client.Do(httpReq)
	if err != nil {
		return fmt.Errorf("Health check failed to connect to server: %v", err)
	} else if resp.StatusCode != 200 {
		return fmt.Errorf("Health check returned unhealthy status: %s", resp.Status)
	}
	log.Printf("health check success! Got status: %s", resp.Status)
	return nil
}

// sendRequest sets up and sends the relevant HTTP request to the server and returns the HTTP response.
func sendRequest(rpcName string, req string, conn *HTTPConnection) (string, error) {
	httpReq, err := http.NewRequest("POST", conn.getURL(rpcName), bytes.NewBuffer([]byte(req)))
	httpReq.Header.Set("Content-Type", "application/json")
	httpReq.Header.Set("Authorization", conn.credentials)
	log.Printf("%v Request. Sent(unix): %s, Url: %v, Method: %v, Header: %v, Body: %v\n", rpcName, time.Now().UTC().Format(time.RFC850), httpReq.URL, httpReq.Method, httpReq.Header, httpReq.Body)

	httpResp, err := conn.client.Do(httpReq)
	if err != nil {
		return "", fmt.Errorf("invalid response. %s yielded error: %v", rpcName, err)
	}
	defer httpResp.Body.Close()
	bodyBytes, err := ioutil.ReadAll(httpResp.Body)
	if err != nil {
		return "", fmt.Errorf("Could not read http response body")
	}
	bodyString := string(bodyBytes)
	log.Printf("%v Response. Received(unix): %s, Response %v\n", rpcName, time.Now().UTC().Format(time.RFC850), bodyString)
	return bodyString, nil
}

// CheckAvailability performs a maps booking availability check on all supplied availability slots. This function
// will return all slots with a valid return.
func CheckAvailability(a *fpb.Availability, conn *HTTPConnection) error {
	slot, err := utils.BuildSlotFrom(a)
	if err != nil {
		return fmt.Errorf("unable to build request for check availability flow. err: %v, availability record: %v", err, a.String())
	}
	reqPB := &mpb.CheckAvailabilityRequest{
		Slot: slot,
	}
	req, err := conn.marshaler.MarshalToString(reqPB)
	if err != nil {
		return fmt.Errorf("Could not convert pb3 to json: %v", reqPB)
	}
	httpResp, err := sendRequest("CheckAvailability", req, conn)
	if err != nil {
		return fmt.Errorf("invalid response. CheckAvailability yielded error: %v", err)
	}
	var resp mpb.CheckAvailabilityResponse
	if err := jsonpb.UnmarshalString(httpResp, &resp); err != nil {
		return fmt.Errorf("CheckAvailability: Could not parse HTTP response to pb3: %v", err)
	}

	if diff := cmp.Diff(resp.GetSlot(), slot, cmp.Comparer(proto.Equal)); diff != "" {
		return fmt.Errorf("invalid response. CheckAvailability slots differ (-got +want)\n%s", diff)
	}

	if resp.GetCountAvailable() == 0 {
		return errors.New("no count available in response")
	}

	return nil
}

// CreateBooking attempts to create bookings from availability slots.
func CreateBooking(a *fpb.Availability, conn *HTTPConnection) (*mpb.Booking, error) {
	slot, err := utils.BuildSlotFrom(a)
	if err != nil {
		return nil, fmt.Errorf("unable to build request for check availability flow. err: %v, availability record: %v", err, a.String())
	}

	gen := rand.New(rand.NewSource(time.Now().UnixNano()))
	// Lease currently unsupported.
	reqPB := &mpb.CreateBookingRequest{
		Slot: slot,
		UserInformation: &mpb.UserInformation{
			UserId:     userID,
			GivenName:  firstName,
			FamilyName: lastName,
			Telephone:  telephone,
			Email:      email,
		},
		PaymentInformation: &mpb.PaymentInformation{
			PrepaymentStatus: mpb.PrepaymentStatus_PREPAYMENT_NOT_PROVIDED,
		},
		IdempotencyToken: strconv.Itoa(gen.Intn(1000000)),
	}
	req, err := conn.marshaler.MarshalToString(reqPB)
	if err != nil {
		return nil, fmt.Errorf("Could not convert pb3 to json: %v", reqPB)
	}

	httpResp, err := sendRequest("CreateBooking", req, conn)
	if err != nil {
		return nil, fmt.Errorf("invalid response. CreateBooking  yielded error: %v", err)
	}
	var resp mpb.CreateBookingResponse
	if err := jsonpb.UnmarshalString(httpResp, &resp); err != nil {
		return nil, fmt.Errorf("CreateBooking: Could not parse HTTP response to pb3: %v", err)
	}

	if resp.GetBookingFailure() != nil {
		return nil, fmt.Errorf("invalid response. CreateBooking failed with booking failure %v", resp.GetBookingFailure())
	}

	b := resp.GetBooking()
	if iE := utils.ValidateBooking(b, &mpb.Booking{
		Slot:               reqPB.GetSlot(),
		UserInformation:    reqPB.GetUserInformation(),
		PaymentInformation: reqPB.GetPaymentInformation(),
	}); iE != nil {
		return nil, fmt.Errorf("invalid response. CreateBooking invalid: %s", iE.Error())
	}

	// Perform idempotency test.
	log.Printf("Idempotency check -- CreateBooking Request. Sent(unix): %s, Request %s", time.Now().UTC().Format(time.RFC850), reqPB.String())
	idemHTTPResp, err := sendRequest("CreateBooking", req, conn)
	if err != nil {
		return nil, fmt.Errorf("invalid response. Idempotency check yielded error: %v", err)
	}
	var idemResp mpb.CreateBookingResponse
	if err := jsonpb.UnmarshalString(idemHTTPResp, &idemResp); err != nil {
		return nil, fmt.Errorf("CreateBooking idem: Could not parse HTTP response to pb3: %v", err)
	}

	if diff := cmp.Diff(idemResp, resp); diff != "" {
		return b, fmt.Errorf("Idempotency check invalid (-got +want)\n%s", diff)
	}

	return b, nil
}

// ListBookings calls the maps booking ListBookings rpc and compares the return with all input bookings.
func ListBookings(tB Bookings, conn *HTTPConnection) (Bookings, error) {
	reqPB := &mpb.ListBookingsRequest{
		UserId: userID,
	}
	req, err := conn.marshaler.MarshalToString(reqPB)
	if err != nil {
		return nil, fmt.Errorf("Could not convert pb3 to json: %v", reqPB)
	}
	httpResp, err := sendRequest("ListBookings", req, conn)
	if err != nil {
		return nil, fmt.Errorf("invalid response. ListBookings yielded error: %v. Abandoning all booking from this flow", err)
	}
	var resp mpb.ListBookingsResponse
	if err := jsonpb.UnmarshalString(httpResp, &resp); err != nil {
		return nil, fmt.Errorf("ListBookings: Could not parse HTTP response to pb3: %v", err)
	}

	gB := Bookings(resp.GetBookings())
	if len(tB) == 0 {
		log.Printf("ListBookings returning %d found bookings", len(gB))
		return gB, nil
	}
	if len(gB) != len(tB) {
		log.Printf("ListBookings number of bookings differed unexpectedly. Got: %d, Want: %d.", len(gB), len(tB))
	}
	sort.Sort(gB)
	sort.Sort(tB)
	var out Bookings
	for i := 0; i < len(tB); i++ {
		if iE := utils.ValidateBooking(gB[i], tB[i]); iE != nil {
			log.Printf("ListBookings invalid, %s, abandoning slot %d/%d", iE.Error(), i, len(tB))
			continue
		}
		out = append(out, tB[i])
	}
	log.Printf("ListBookings returning %d bookings", len(out))
	return out, nil
}

// GetBookingStatus checks that all input bookings are in an acceptable state.
func GetBookingStatus(b *mpb.Booking, conn *HTTPConnection) error {
	reqPB := &mpb.GetBookingStatusRequest{
		BookingId: b.GetBookingId(),
	}

	req, err := conn.marshaler.MarshalToString(reqPB)
	if err != nil {
		return fmt.Errorf("Could not convert pb3 to json: %v", reqPB)
	}
	httpResp, err := sendRequest("GetBookingStatus", req, conn)
	if err != nil {
		return fmt.Errorf("invalid response. GetBookingStatus yielded error: %v", err)
	}
	var resp mpb.GetBookingStatusResponse
	if err := jsonpb.UnmarshalString(httpResp, &resp); err != nil {
		return fmt.Errorf("GetBookingsStatus: Could not parse HTTP response to pb3: %v", err)
	}

	if diff := cmp.Diff(resp.GetBookingStatus(), mpb.BookingStatus_CONFIRMED); diff != "" {
		return fmt.Errorf("invalid response. BookingStatus differ (-got +want)\n%s", diff)
	}

	return nil
}

// CancelBooking is a clean up method that cancels all supplied bookings.
func CancelBooking(bookingID string, conn *HTTPConnection) error {
	reqPB := &mpb.UpdateBookingRequest{
		Booking: &mpb.Booking{
			BookingId: bookingID,
			Status:    mpb.BookingStatus_CANCELED,
		},
	}
	req, err := conn.marshaler.MarshalToString(reqPB)
	if err != nil {
		return fmt.Errorf("Could not convert pb3 to json: %v", reqPB)
	}
	httpResp, err := sendRequest("UpdateBooking", req, conn)
	if err != nil {
		return fmt.Errorf("invalid response. UpdateBooking yielded error: %v", err)
	}
	var resp mpb.UpdateBookingResponse
	if err := jsonpb.UnmarshalString(httpResp, &resp); err != nil {
		return fmt.Errorf("CancelBooking: Could not parse HTTP response to pb3: %v", err)
	}

	if iE := utils.ValidateBooking(resp.GetBooking(), reqPB.GetBooking()); iE != nil {
		return fmt.Errorf("invalid response. UpdateBooking: %s", iE.Error())
	}
	return nil
}

// Rescheduling will attempt to create a booking, update the booking, then cancel.
func Rescheduling(av []*fpb.Availability, conn *HTTPConnection) error {
	var slots []*fpb.Availability
	for _, v := range utils.BuildMerchantServiceMap(av) {
		// Need at least two slots for reschedule.
		if len(v) <= 1 {
			continue
		}
		slots = v
		break
	}

	if len(slots) == 0 {
		return errors.New("no suitable availability for rescheduling flow. exiting")
	}
	// Book first slot.
	newBooking, err := CreateBooking(slots[0], conn)
	if err != nil {
		return fmt.Errorf("could not complete booking, abandoning rescheduling flow: %v", err)
	}

	// New slot.
	lastAvailability := slots[len(slots)-1]

	reqPB := &mpb.UpdateBookingRequest{
		Booking: &mpb.Booking{
			BookingId: newBooking.GetBookingId(),
			Slot: &mpb.Slot{
				StartSec:    lastAvailability.GetStartSec(),
				DurationSec: lastAvailability.GetDurationSec(),
			},
		},
	}
	req, err := conn.marshaler.MarshalToString(reqPB)
	if err != nil {
		return fmt.Errorf("Rescheduling UpdateBooking: Could not convert pb3 to json: %v", reqPB)
	}
	updateHTTPResp, err := sendRequest("UpdateBooking", req, conn)
	var resp mpb.CreateBookingResponse
	if err := jsonpb.UnmarshalString(updateHTTPResp, &resp); err != nil {
		return fmt.Errorf("Rescheduling UpdateBooking: Could not parse HTTP response to pb3: %v", err)
	}

	// Update slot before performing diff.
	newBooking.GetSlot().StartSec = lastAvailability.GetStartSec()
	newBooking.GetSlot().DurationSec = lastAvailability.GetDurationSec()

	if iE := utils.ValidateBooking(resp.GetBooking(), newBooking); iE != nil {
		return fmt.Errorf("invalid response. UpdateBooking: %s, abandoning slot 1/1", iE.Error())
	}
	return CancelBooking(resp.GetBooking().GetBookingId(), conn)
}

// CheckOrderFulfillability attempts to send a CheckOrderFulfillabilityRequest
// to the connection endpoint and diff the results with what are expected.
func CheckOrderFulfillability(merchantID string, lineItems []*mpb.LineItem, conn *HTTPConnection) error {
	reqPB := &mpb.CheckOrderFulfillabilityRequest{
		MerchantId: merchantID,
		Item:       lineItems,
	}
	req, err := conn.marshaler.MarshalToString(reqPB)
	if err != nil {
		return fmt.Errorf("Could not convert pb3 to json: %v", reqPB)
	}
	httpResp, err := sendRequest("CheckOrderFulfillability", req, conn)
	if err != nil {
		return fmt.Errorf("invalid response. CheckOrderFulfillability yielded error: %v", err)
	}
	var resp mpb.CheckOrderFulfillabilityResponse
	if err := jsonpb.UnmarshalString(httpResp, &resp); err != nil {
		return fmt.Errorf("CheckOrderFulfillability: Could not parse HTTP response to pb3: %v", err)
	}

	orderFulfillability := resp.GetFulfillability()
	// TODO(ccawdrey): Add validation cases for other OrderFulFillability enums.
	if diff := cmp.Diff(orderFulfillability.GetResult(), mpb.OrderFulfillability_CAN_FULFILL); diff != "" {
		return fmt.Errorf("invalid response. CheckOrderFulfillability.Fulfillability.OrderFulfillabilityResult differ (-got +want)\n%s", diff)
	}
	if orderFulfillability.GetUnfulfillableReason() != "" {
		return errors.New("invalid response. CheckOrderFulfillability.UnfulfillableReason should be empty")
	}

	var respLineItems []*mpb.LineItem
	for _, lineItemFulfillability := range orderFulfillability.GetItemFulfillability() {
		if diff := cmp.Diff(lineItemFulfillability.GetResult(), mpb.LineItemFulfillability_CAN_FULFILL); diff != "" {
			return fmt.Errorf("invalid response. CheckOrderFulfillability.Fulfillability.ItemFulfillability.Result for LineItem %v -- differ (-got +want)\n%s", lineItemFulfillability.GetItem(), diff)
		}
		if lineItemFulfillability.GetUnfulfillableReason() != "" {
			return errors.New("invalid response. CheckOrderFulfillability.Fulfillability.ItemFulfillability.UnfulfillableReason should be empty")
		}

		respLineItems = append(respLineItems, lineItemFulfillability.GetItem())
	}

	if err = utils.ValidateLineItems(respLineItems, lineItems, false); err != nil {
		return fmt.Errorf("invalid response. CheckOrderFulfillability %v", err)
	}

	return nil
}

// CreateOrder will attempt to build an order from a merchant id and array of line orders.
func CreateOrder(merchantID string, lineItems []*mpb.LineItem, conn *HTTPConnection) (*mpb.Order, error) {
	gen := rand.New(rand.NewSource(time.Now().UnixNano()))

	reqOrder := &mpb.Order{
		UserInformation: &mpb.UserInformation{
			UserId:     userID,
			GivenName:  firstName,
			FamilyName: lastName,
			Telephone:  telephone,
			Email:      email,
		},
		PaymentInformation: &mpb.PaymentInformation{
			PrepaymentStatus: mpb.PrepaymentStatus_PREPAYMENT_NOT_PROVIDED,
		},
		MerchantId: merchantID,
		Item:       lineItems,
	}
	reqPB := &mpb.CreateOrderRequest{
		Order:            reqOrder,
		IdempotencyToken: strconv.Itoa(gen.Intn(1000000)),
	}

	req, err := conn.marshaler.MarshalToString(reqPB)
	if err != nil {
		return nil, fmt.Errorf("Could not convert pb3 to json: %v", reqPB)
	}
	httpResp, err := sendRequest("CreateOrder", req, conn)
	if err != nil {
		return nil, fmt.Errorf("invalid response. CreateOrder yielded error: %v", err)
	}
	var resp mpb.CreateOrderResponse
	if err := jsonpb.UnmarshalString(httpResp, &resp); err != nil {
		return nil, fmt.Errorf("CreateOrder: Could not parse HTTP response to pb3: %v", err)
	}

	if resp.GetOrderFailure() != nil {
		return nil, fmt.Errorf("invalid response. CreateOrder contains OrderFailure for request %v", reqPB)
	}

	if err = utils.ValidateOrder(*resp.GetOrder(), *reqOrder); err != nil {
		return nil, fmt.Errorf("invalid response. CreateOrder %v", err)
	}

	// Perform idempotency test.
	log.Printf("Idempotency check")
	idemHTTPResp, err := sendRequest("CreateOrder", req, conn)
	if err != nil {
		return nil, fmt.Errorf("invalid response. Idempotency check yielded error: %v", err)
	}
	var idemResp mpb.CreateOrderResponse
	if err := jsonpb.UnmarshalString(idemHTTPResp, &idemResp); err != nil {
		return nil, fmt.Errorf("CreateOrder idem: Could not parse HTTP response to pb3: %v", err)
	}

	if idemResp.GetOrderFailure() != nil {
		return nil, errors.New("Idempotency check invalid. CreateOrder contains OrderFailure")
	}
	if err = utils.ValidateOrder(*idemResp.GetOrder(), *resp.GetOrder()); err != nil {
		return nil, fmt.Errorf("Idempotency check invalid  %v", err)
	}

	return resp.GetOrder(), nil
}

func sendListOrdersRequest(reqPB *mpb.ListOrdersRequest, conn *HTTPConnection) (mpb.ListOrdersResponse, error) {
	req, err := conn.marshaler.MarshalToString(reqPB)
	if err != nil {
		return mpb.ListOrdersResponse{}, fmt.Errorf("Could not convert pb3 to json: %v", reqPB)
	}
	httpResp, err := sendRequest("ListOrders", req, conn)
	if err != nil {
		return mpb.ListOrdersResponse{}, fmt.Errorf("invalid response. ListOrders yielded error: %v", err)
	}
	var resp mpb.ListOrdersResponse
	if err := jsonpb.UnmarshalString(httpResp, &resp); err != nil {
		return resp, fmt.Errorf("ListOrders: Could not parse HTTP response to pb3: %v", err)
	}

	return resp, nil
}

// ListOrders first checks that the number and contents of the server's order state
// are consistent with what the test client assumes is present.
func ListOrders(orders []*mpb.Order, conn *HTTPConnection) error {
	if len(orders) == 0 {
		return errors.New("at least one order must be present for ListOrders to succeed")
	}

	// UserId check first.
	reqPB := &mpb.ListOrdersRequest{
		Ids: &mpb.ListOrdersRequest_UserId{userID},
	}
	respUser, err := sendListOrdersRequest(reqPB, conn)
	if err != nil {
		return err
	}
	if err = utils.ValidateOrders(respUser.GetOrder(), orders); err != nil {
		return fmt.Errorf("invalid response. ListOrders %v for request %v", err, reqPB)
	}

	// Still here? OrderId check.
	reqPB.Reset()
	var orderIDs mpb.ListOrdersRequest_OrderIds
	for _, order := range orders {
		orderIDs.OrderId = append(orderIDs.OrderId, order.GetOrderId())
	}
	reqPB.Ids = &mpb.ListOrdersRequest_OrderIds_{&orderIDs}

	respOrder, err := sendListOrdersRequest(reqPB, conn)
	if err != nil {
		return err
	}
	if err = utils.ValidateOrders(respOrder.GetOrder(), orders); err != nil {
		return fmt.Errorf("invalid response. ListOrders %v for request %v", err, reqPB)
	}

	return nil
}

// BatchGetWaitEstimates calls the partners API and verifies the returned WaitEstimates.
func BatchGetWaitEstimates(s *fpb.Service, conn *HTTPConnection) error {
	rules := s.GetWaitlistRules()

	ps := make([]int32, rules.GetMaxPartySize()-rules.GetMinPartySize())
	for i := range ps {
		ps[i] = rules.GetMinPartySize() + int32(i)
	}
	reqPB := &wpb.BatchGetWaitEstimatesRequest{
		MerchantId: s.GetMerchantId(),
		ServiceId:  s.GetServiceId(),
		PartySize:  ps,
	}
	req, err := conn.marshaler.MarshalToString(reqPB)
	if err != nil {
		return fmt.Errorf("Could not convert pb3 to json: %v", reqPB)
	}
	httpResp, err := sendRequest("BatchGetWaitEstimates", req, conn)
	if err != nil {
		return fmt.Errorf("invalid response. BatchGetWaitEstimates yielded error: %v", err)
	}
	var resp wpb.BatchGetWaitEstimatesResponse
	if err := jsonpb.UnmarshalString(httpResp, &resp); err != nil {
		return fmt.Errorf("BatchGetWaitEstimates: Could not parse HTTP response to pb3: %v", err)
	}

	if resp.GetWaitlistStatus() == wpb.WaitlistStatus_WAITLIST_STATUS_UNSPECIFIED {
		return errors.New("BatchGetWaitEstimates: waitlist status was not specified in response")
	} else if resp.GetWaitlistStatus() != wpb.WaitlistStatus_OPEN {
		// Waitlist is closed. No further validation necessary.
		return nil
	}

	// Waitlist status is OPEN
	for _, we := range resp.GetWaitEstimate() {
		if err := utils.ValidateWaitEstimate(we); err != nil {
			return fmt.Errorf("BatchGetWaitEstimates invalid, %s, service id: %s",
				err.Error(), s.GetServiceId())
		} else if we.GetPartySize() > rules.GetMaxPartySize() ||
			we.GetPartySize() < rules.GetMinPartySize() {
			return fmt.Errorf("batchGetWaitEstimates: Party size outside of min/max for service id: %s."+
				"returned party size: %d, min party size: %d, max party size: %d",
				s.GetServiceId(), we.GetPartySize(), rules.GetMinPartySize(), rules.GetMaxPartySize())
		}
	}
	return nil
}

// CreateWaitlistEntry attempts to create waitlist entries from a service.
// The max party size listed for the service's waitlist rules is used for
// the waitlist entry's party size.
func CreateWaitlistEntry(s *fpb.Service, conn *HTTPConnection) (string, error) {
	gen := rand.New(rand.NewSource(time.Now().UnixNano()))

	reqPB := &wpb.CreateWaitlistEntryRequest{
		MerchantId: s.GetMerchantId(),
		ServiceId:  s.GetServiceId(),
		PartySize:  s.GetWaitlistRules().GetMaxPartySize(),
		UserInformation: &wpb.UserInformation{
			UserId:     userID,
			GivenName:  firstName,
			FamilyName: lastName,
			Telephone:  telephone,
			Email:      email,
		},
		IdempotencyToken: strconv.Itoa(gen.Intn(1000000)),
	}
	if s.GetWaitlistRules().GetSupportsAdditionalRequest() {
		reqPB.AdditionalRequest = "test additional request"
	}
	req, err := conn.marshaler.MarshalToString(reqPB)
	if err != nil {
		return "", fmt.Errorf("Could not convert pb3 to json: %v", reqPB)
	}

	httpResp, err := sendRequest("CreateWaitlistEntry", req, conn)
	if err != nil {
		return "", fmt.Errorf("invalid response. CreateWaitlistEntry  yielded error: %v", err)
	}
	var resp wpb.CreateWaitlistEntryResponse
	if err := jsonpb.UnmarshalString(httpResp, &resp); err != nil {
		return "", fmt.Errorf("CreateWaitlistEntry: Could not parse HTTP response to pb3: %v", err)
	}

	if resp.GetWaitlistBusinessLogicFailure() != nil {
		return "", fmt.Errorf("invalid response. CreateWaitlistEntry failed with business logic failure %v",
			resp.GetWaitlistBusinessLogicFailure())
	}

	if resp.GetWaitlistEntryId() == "" {
		return "", fmt.Errorf("invalid response. CreateWaitlistEntry missing waitlist entry id for service: %s",
			s.GetServiceId())
	}

	// Perform idempotency test.
	log.Printf("Idempotency check -- CreateWaitlistEntry Request. Sent(unix): %s, Request %s", time.Now().UTC().Format(time.RFC850), reqPB.String())
	idemHTTPResp, err := sendRequest("CreateWaitlistEntry", req, conn)
	if err != nil {
		return "", fmt.Errorf("invalid response. Idempotency check yielded error: %v", err)
	}
	var idemResp wpb.CreateWaitlistEntryResponse
	if err := jsonpb.UnmarshalString(idemHTTPResp, &idemResp); err != nil {
		return "", fmt.Errorf("CreateWaitlistEntry idem: Could not parse HTTP response to pb3: %v", err)
	}

	if diff := cmp.Diff(idemResp, resp); diff != "" {
		return "", fmt.Errorf("Idempotency check invalid (-got +want)\n%s for service: %s", diff, s.GetServiceId())
	}

	return resp.GetWaitlistEntryId(), nil
}

// GetWaitlistEntry retrieves and validates the booking for the specified
// waitlist entry id.
func GetWaitlistEntry(id string, conn *HTTPConnection) (*wpb.WaitlistEntry, error) {
	reqPB := &wpb.GetWaitlistEntryRequest{
		WaitlistEntryId: id,
	}

	req, err := conn.marshaler.MarshalToString(reqPB)
	if err != nil {
		return nil, fmt.Errorf("Could not convert pb3 to json: %v", reqPB)
	}
	httpResp, err := sendRequest("GetWaitlistEntry", req, conn)
	if err != nil {
		return nil, fmt.Errorf("invalid response. GetWaitlistEntry yielded error: %v", err)
	}
	var resp wpb.GetWaitlistEntryResponse
	if err := jsonpb.UnmarshalString(httpResp, &resp); err != nil {
		return nil, fmt.Errorf("GetWaitlistEntry: Could not parse HTTP response to pb3: %v", err)
	}

	if iE := utils.ValidateWaitlistEntry(resp.GetWaitlistEntry()); iE != nil {
		return nil, fmt.Errorf("invalid response. GetWaitlistEntry: %s", iE.Error())
	}

	return resp.GetWaitlistEntry(), nil
}

// DeleteWaitlistEntry makes a request to delete the waitlist entry.
func DeleteWaitlistEntry(id string, conn *HTTPConnection) error {
	reqPB := &wpb.DeleteWaitlistEntryRequest{
		WaitlistEntryId: id,
	}

	req, err := conn.marshaler.MarshalToString(reqPB)
	if err != nil {
		return fmt.Errorf("Could not convert pb3 to json: %v", reqPB)
	}

	if _, err = sendRequest("DeleteWaitlistEntry", req, conn); err != nil {
		return fmt.Errorf("invalid response. DeleteWaitlistEntry yielded error: %v", err)
	}

	return nil
}
