/*
Copyright 2019 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"
	"context"
	"crypto/tls"
	"crypto/x509"
	"encoding/base64"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"sort"
	"strconv"
	"strings"
	"time"

	epb "github.com/golang/protobuf/ptypes/empty"
	"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/v3waitlist"
)

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

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 utils.HTTPConnection object
// with a given server address and username/password.
func InitHTTPConnection(serverAddr string, credentialsFile string, caFile string, fullServerName string) (*utils.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 &utils.HTTPConnection{
		Client: &http.Client{
			Transport: &http.Transport{TLSClientConfig: config},
		},
		Credentials: credentials,
		Marshaler:   &jsonpb.Marshaler{OrigName: true},
		BaseURL:     protocol + "://" + serverAddr,
	}, nil
}

// 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(ctx context.Context, logger *log.Logger, conn *utils.HTTPConnection) error {
	utils.LogFlow(logger, "Health Check", "Start")
	defer utils.LogFlow(logger, "Health Check", "End")

	fmt.Println(conn.GetURL("HealthCheck"))
	httpReq, err := http.NewRequest("GET", conn.GetURL("HealthCheck"), nil)
	reqCtx, cancel := context.WithTimeout(ctx, reqTimeout)
	defer cancel()
	httpReq = httpReq.WithContext(reqCtx)
	httpReq.Header.Set("Authorization", conn.Credentials)

	// See if we get a response.
	resp, err := conn.Client.Do(httpReq)
	if err := ctx.Err(); err != nil {
		panic(fmt.Sprintf("Encountered context error: %s", err.Error()))
	}
	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)
	}
	logger.Printf("health check success! Got status: %s", resp.Status)
	return nil
}

func getLogSafeHeader(header http.Header) http.Header {
	logHeader := make(http.Header)
	for k, v := range header {
		if k == "Authorization" {
			logHeader.Set("Authorization", "VALUE REDACTED.")
			continue
		}
		logHeader[k] = v
	}
	return logHeader
}

// sendRequest sets up and sends the relevant HTTP request to the server and returns the HTTP response.
func sendRequest(ctx context.Context, logger *log.Logger, rpcName string, req string, conn *utils.HTTPConnection) (string, error) {
	httpReq, err := http.NewRequest("POST", conn.GetURL(rpcName), bytes.NewBuffer([]byte(req)))
	reqCtx, cancel := context.WithTimeout(ctx, reqTimeout)
	defer cancel()
	httpReq = httpReq.WithContext(reqCtx)
	httpReq.Header.Set("Content-Type", "application/json")
	httpReq.Header.Set("Authorization", conn.Credentials)
	logHeader := getLogSafeHeader(httpReq.Header)
	logger.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, logHeader, httpReq.Body)

	httpResp, err := conn.Client.Do(httpReq)
	if err := ctx.Err(); err != nil {
		panic(fmt.Sprintf("Encountered context error: %s", err.Error()))
	}
	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)
	logger.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
// returns any errors when trying to call the CheckAvailability RPC.
func CheckAvailability(ctx context.Context, logger *log.Logger, a *fpb.Availability, conn *utils.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(ctx, logger, "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
}

// BatchAvailabilityLookup performs a maps booking batch availability lookup on all supplied availability slots. This function
// returns any errors when trying to call the BatchAvailabilityLookup RPC.
func BatchAvailabilityLookup(ctx context.Context, logger *log.Logger, av []*fpb.Availability, conn *utils.HTTPConnection) error {
	reqPB, err := utils.BuildBatchAvailabilityLookupRequestFrom(av)
	if err != nil {
		return fmt.Errorf("unable to build request for batch availability lookup flow. err: %v, availability records: %v", err, av)
	}
	req, err := conn.Marshaler.MarshalToString(reqPB)
	if err != nil {
		return fmt.Errorf("Could not convert pb3 to json: %v", reqPB)
	}
	httpResp, err := sendRequest(ctx, logger, "BatchAvailabilityLookup", req, conn)
	if err != nil {
		return fmt.Errorf("invalid response. BatchAvailabilityLookup yielded error: %v", err)
	}
	var resp mpb.BatchAvailabilityLookupResponse
	if err := jsonpb.UnmarshalString(httpResp, &resp); err != nil {
		return fmt.Errorf("BatchAvailabilityLookup: Could not parse HTTP response to pb3: %v", err)
	}
	if len(resp.GetSlotTimeAvailability()) != len(reqPB.GetSlotTime()) {
		return fmt.Errorf("invalid response. BatchAvailabilityLookup response.size and request.size differ: %v vs %v", len(resp.GetSlotTimeAvailability()), len(reqPB.GetSlotTime()))
	}
	diffCount := 0
	for i := 0; i < len(reqPB.GetSlotTime()); i++ {
		slotTimeReq := reqPB.GetSlotTime()[i]
		slotTimeResp := resp.GetSlotTimeAvailability()[i].GetSlotTime()
		if diff := cmp.Diff(slotTimeReq, slotTimeResp, cmp.Comparer(proto.Equal)); diff != "" {
			logger.Printf("Slot %v differs: req=%v, resp=%v", i, slotTimeReq, slotTimeResp)
			diffCount++
		}
	}
	if diffCount > 0 {
		return fmt.Errorf("invalid response. Found %v diffs", diffCount)
	}
	return nil
}

// CreateBooking attempts to create bookings from availability slots.
func CreateBooking(ctx context.Context, logger *log.Logger, a *fpb.Availability, conn *utils.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(ctx, logger, "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.
	logger.Printf("Idempotency check -- CreateBooking Request. Sent(unix): %s, Request %s", time.Now().UTC().Format(time.RFC850), reqPB.String())
	idemHTTPResp, err := sendRequest(ctx, logger, "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(ctx context.Context, logger *log.Logger, tB Bookings, conn *utils.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(ctx, logger, "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 {
		logger.Printf("ListBookings returning %d found bookings", len(gB))
		return gB, nil
	}
	if len(gB) != len(tB) {
		logger.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 {
			logger.Printf("ListBookings invalid, %s, abandoning slot %d/%d", iE.Error(), i, len(tB))
			continue
		}
		out = append(out, tB[i])
	}
	logger.Printf("ListBookings returning %d bookings", len(out))
	return out, nil
}

// GetBookingStatus checks that all input bookings are in an acceptable state.
func GetBookingStatus(ctx context.Context, logger *log.Logger, b *mpb.Booking, conn *utils.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(ctx, logger, "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(ctx context.Context, logger *log.Logger, bookingID string, conn *utils.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(ctx, logger, "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)
	}

	// We only care that the correct booking was cancelled. The rest of the response content
	// is not relevant.
	compareBooking := &mpb.Booking{
		BookingId: resp.GetBooking().GetBookingId(),
		Status:    resp.GetBooking().GetStatus(),
	}
	if iE := utils.ValidateBooking(compareBooking, 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(ctx context.Context, logger *log.Logger, av []*fpb.Availability, conn *utils.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(ctx, logger, 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(ctx, logger, "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(ctx, logger, resp.GetBooking().GetBookingId(), conn)
}

// CheckOrderFulfillability attempts to send a CheckOrderFulfillabilityRequest
// to the connection endpoint and diff the results with what are expected.
func CheckOrderFulfillability(ctx context.Context, logger *log.Logger, merchantID string, lineItems []*mpb.LineItem, conn *utils.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(ctx, logger, "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()
	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(ctx context.Context, logger *log.Logger, merchantID string, lineItems []*mpb.LineItem, conn *utils.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(ctx, logger, "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.
	logger.Printf("Idempotency check")
	idemHTTPResp, err := sendRequest(ctx, logger, "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(ctx context.Context, logger *log.Logger, reqPB *mpb.ListOrdersRequest, conn *utils.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(ctx, logger, "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(ctx context.Context, logger *log.Logger, orders []*mpb.Order, conn *utils.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(ctx, logger, 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(ctx, logger, 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(ctx context.Context, logger *log.Logger, s *fpb.Service, conn *utils.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(ctx, logger, "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. Wait estimate should not be provided.
		if len(resp.GetWaitEstimate()) > 0 {
			return errors.New("BatchGetWaitEstimates: wait estimate must not be provided when waitlist is closed")
		}
	}

	// 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(ctx context.Context, logger *log.Logger, s *fpb.Service, conn *utils.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(ctx, logger, "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.
	logger.Printf("Idempotency check -- CreateWaitlistEntry Request. Sent(unix): %s, Request %s", time.Now().UTC().Format(time.RFC850), reqPB.String())
	idemHTTPResp, err := sendRequest(ctx, logger, "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(ctx context.Context, logger *log.Logger, id string, conn *utils.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(ctx, logger, "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(ctx context.Context, logger *log.Logger, id string, conn *utils.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)
	}

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

	var resp epb.Empty
	if err := jsonpb.UnmarshalString(httpResp, &resp); err != nil {
		return fmt.Errorf("DeleteWaitlistEntry: Could not parse HTTP response to pb3: %v. Body should be: {}", err)
	}

	return nil
}
