/*
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 (
	"errors"
	"fmt"
	"log"
	"math/rand"
	"sort"
	"strconv"
	"time"

	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/ptypes"
	"github.com/google/go-cmp/cmp"
	"github.com/maps-booking/utils"
	"golang.org/x/net/context"
	"google.golang.org/genproto/protobuf/field_mask"
	"google.golang.org/grpc"

	mpb "github.com/maps-booking/bookingservice"
	fpb "github.com/maps-booking/feeds"
	hpb "google.golang.org/grpc/health/grpc_health_v1"
)

const (
	userID    = "0"
	firstName = "Jane"
	lastName  = "Doe"
	telephone = "+18007897890"
	email     = "test@example.com"
	service   = "ext.maps.booking.partner.v2.BookingService"
)

// 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 gRPC health check.
func HealthCheck(ctx context.Context, conn *grpc.ClientConn) error {
	utils.LogFlow("Health Check", "Start")
	defer utils.LogFlow("Health Check", "End")

	healthCli := hpb.NewHealthClient(conn)
	req := &hpb.HealthCheckRequest{Service: service}
	// Ignore cancel. Server will take care of it.
	resp, err := healthCli.Check(ctx, req)
	if err != nil {
		return fmt.Errorf("could not complete health check: %v", err)
	}

	if diff := cmp.Diff(resp.Status, hpb.HealthCheckResponse_SERVING); diff != "" {
		return fmt.Errorf("health check invalid (-got +want)\n%s", diff)
	}
	log.Println("health check success!")
	return nil
}

// CheckAvailability beforms a maps booking availability check on all supplied availability slots. This function
// will return all slots with a valid return.
func CheckAvailability(ctx context.Context, a *fpb.Availability, c mpb.BookingServiceClient) 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())
	}

	req := &mpb.CheckAvailabilityRequest{
		Slot: slot,
	}

	log.Printf("CheckAvailability Request. Sent(unix): %s, Request %s", time.Now().UTC().Format(time.RFC850), req.String())
	resp, err := c.CheckAvailability(ctx, req)
	if err != nil {
		return fmt.Errorf("invalid response. CheckAvailability yielded error: %v", err)
	}

	log.Printf("CheckAvailability Response. Received(unix): %s, Response %s", time.Now().UTC().Format(time.RFC850), resp.String())
	if diff := cmp.Diff(resp.GetSlot(), req.GetSlot(), 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(ctx context.Context, a *fpb.Availability, c mpb.BookingServiceClient) (*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.
	req := &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)),
	}

	log.Printf("CreateBooking Request. Sent(unix): %s, Request %s", time.Now().UTC().Format(time.RFC850), req.String())
	resp, err := c.CreateBooking(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("invalid response. CreateBooking  yielded error: %v", err)
	}

	log.Printf("CreateBooking Response. Received(unix): %s, Response %s", time.Now().UTC().Format(time.RFC850), resp.String())
	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:               req.GetSlot(),
		UserInformation:    req.GetUserInformation(),
		PaymentInformation: req.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), req.String())
	idemResp, err := c.CreateBooking(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("invalid response. Idempotency check yielded error: %v", err)
	}

	log.Printf("Idempotency check -- Response. Received(unix): %s, Response %s", time.Now().UTC().Format(time.RFC850), resp.String())
	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, tB Bookings, c mpb.BookingServiceClient) (Bookings, error) {
	var out Bookings
	req := &mpb.ListBookingsRequest{
		UserId: userID,
	}
	log.Printf("ListBookings Request. Sent(unix): %s, Request %s", time.Now().UTC().Format(time.RFC850), req.String())
	resp, err := c.ListBookings(ctx, req)
	if err != nil {
		return out, fmt.Errorf("invalid response. ListBookings yielded error: %v. Abandoning all booking from this flow", err)
	}

	log.Printf("ListBookings Response. Received(unix): %s, Response %s", time.Now().UTC().Format(time.RFC850), resp.String())
	gB := Bookings(resp.GetBookings())
	if len(gB) != len(tB) {
		return out, fmt.Errorf("number of bookings differ, ListBookings invalid. Got: %d, Want: %d. Abandoning all bookings from this flow", len(gB), len(tB))
	}

	sort.Sort(gB)
	sort.Sort(tB)
	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])
	}

	return out, nil
}

// GetBookingStatus checks that all input bookings are in an acceptable state.
func GetBookingStatus(ctx context.Context, b *mpb.Booking, c mpb.BookingServiceClient) error {
	req := &mpb.GetBookingStatusRequest{
		BookingId: b.GetBookingId(),
	}

	log.Printf("GetBookingStatus Request. Sent(unix): %s, Request %s", time.Now().UTC().Format(time.RFC850), req.String())
	resp, err := c.GetBookingStatus(ctx, req)
	if err != nil {
		return fmt.Errorf("invalid response. GetBookingStatus yielded error: %v", err)
	}

	log.Printf("GetBookingStatus Response. Received(unix): %s, Response %s", time.Now().UTC().Format(time.RFC850), resp.String())
	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, b *mpb.Booking, c mpb.BookingServiceClient) error {
	b.Status = mpb.BookingStatus_CANCELED
	req := &mpb.UpdateBookingRequest{
		UpdateMask: &field_mask.FieldMask{
			Paths: []string{"status"},
		},
		Booking: b,
	}

	log.Printf("UpdateBooking Request. Sent(unix): %s, Request %s", time.Now().UTC().Format(time.RFC850), req.String())
	resp, err := c.UpdateBooking(ctx, req)
	if err != nil {
		return fmt.Errorf("invalid response. UpdateBooking yielded error: %v", err)
	}

	log.Printf("UpdateBooking Response. Received(unix): %s, Response %s", time.Now().UTC().Format(time.RFC850), resp.String())
	if iE := utils.ValidateBooking(resp.GetBooking(), req.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, av []*fpb.Availability, c mpb.BookingServiceClient) 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, slots[0], c)
	if err != nil {
		return fmt.Errorf("could not complete booking, abandoning rescheduling flow: %v", err)
	}

	slot := newBooking.GetSlot()
	// New slot.
	lastAvailability := slots[len(slots)-1]
	startTime, err := ptypes.TimestampProto(time.Unix(lastAvailability.GetStartSec(), 0))
	if err != nil {
		return fmt.Errorf("could not complete update, abandoning rescheduling flow: %v", err)
	}
	slot.StartTime = startTime
	slot.Duration = ptypes.DurationProto(time.Duration(lastAvailability.GetDurationSec()) * time.Second)

	req := &mpb.UpdateBookingRequest{
		UpdateMask: &field_mask.FieldMask{
			Paths: []string{"slot.start_time", "slot.duration"},
		},
		Booking: newBooking,
	}

	log.Printf("UpdateBooking Request. Sent(unix): %s, Request %s", time.Now().UTC().Format(time.RFC850), req.String())
	resp, err := c.UpdateBooking(ctx, req)
	if err != nil {
		return fmt.Errorf("invalid response. UpdateBooking yielded error: %v", err)
	}

	log.Printf("UpdateBooking Response. Received(unix): %s, Response %s", time.Now().UTC().Format(time.RFC850), resp.String())
	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, resp.GetBooking(), c)
}
