/*
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 booking contains test logic for booking related endpoints.
package booking

import (
	"context"
	"log"

	"github.com/maps-booking-v3/api"
	"github.com/maps-booking-v3/utils"

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

// GenerateBookings creates bookings from an availability feed.
func GenerateBookings(ctx context.Context, logger *log.Logger, av []*fpb.Availability, stats *utils.TestSummary, conn *utils.HTTPConnection, config *utils.Config) api.Bookings {
	logger.Println("no previous bookings to use, acquiring new inventory")
	utils.LogFlow(logger, "Generate Fresh Inventory", "Start")
	defer utils.LogFlow(logger, "Generate Fresh Inventory", "End")

	var out api.Bookings
	totalSlots := len(av)
	var available []*fpb.Availability
	if config.BookingUseBal {
		if avSlot, err := api.AvailableSlotsFromBAL(ctx, logger, av, conn); err != nil {
			logger.Printf("BAL error: %s. skipping %d slots", err.Error(), totalSlots)
			stats.BookingBatchAvailabilityLookupErrors++
		} else if len(avSlot) > 0 {
			available = append(available, avSlot...)
			stats.BookingBatchAvailabilityLookupSuccess++
		}
	} else {
		for i, a := range av {
			if err := api.CheckAvailability(ctx, logger, a, conn); err != nil {
				logger.Printf("%s. skipping slot %d/%d", err.Error(), i, totalSlots)
				stats.BookingCheckAvailabilityErrors++
				continue
			}
			available = append(available, a)
			stats.BookingCheckAvailabilitySuccess++
		}
	}

	totalSlots = len(available)
	for i, a := range available {
		booking, err := api.CreateBooking(ctx, logger, a, conn)
		if err != nil {
			logger.Printf("%s. skipping slot %d/%d", err.Error(), i, totalSlots)
			stats.BookingCreateBookingErrors++
			continue
		}
		out = append(out, booking)
		stats.BookingCreateBookingSuccess++
	}
	return out
}

func logStats(stats *utils.TestSummary, logger *log.Logger, config *utils.Config) {
	logger.Println("\n************* Begin Stats *************\n")
	var totalErrors int
	if config.BookingHealthFlow || config.BookingAllFlows {
		if stats.BookingHealthCheckSuccess {
			logger.Println("HealthCheck Succeeded")
		} else {
			totalErrors++
			logger.Println("HealthCheck Failed")
		}
	}
	if config.BookingCheckFlow || config.BookingAllFlows {
		if config.BookingUseBal {
			totalErrors += stats.BookingBatchAvailabilityLookupErrors
			logger.Printf("BatchAvailabilityLookup Errors: %d/%d", stats.BookingBatchAvailabilityLookupErrors, stats.BookingBatchAvailabilityLookupErrors+stats.BookingBatchAvailabilityLookupSuccess)
		} else {
			totalErrors += stats.BookingCheckAvailabilityErrors
			logger.Printf("CheckAvailability Errors: %d/%d", stats.BookingCheckAvailabilityErrors, stats.BookingCheckAvailabilityErrors+stats.BookingCheckAvailabilitySuccess)
		}
	}
	if config.BookingBookFlow || config.BookingAllFlows {
		totalErrors += stats.BookingCreateBookingErrors
		logger.Printf("CreateBooking Errors: %d/%d", stats.BookingCreateBookingErrors, stats.BookingCreateBookingErrors+stats.BookingCreateBookingSuccess)
	}
	if config.BookingListFlow || config.BookingAllFlows || config.BookingCancelAllBookings {
		if stats.BookingListBookingsSuccess {
			logger.Println("ListBookings Succeeded")
		} else {
			totalErrors++
			logger.Println("ListBookings Failed")
		}
	}
	if config.BookingStatusFlow || config.BookingAllFlows {
		totalErrors += stats.BookingGetBookingStatusErrors
		logger.Printf("GetBookingStatus Errors: %d/%d", stats.BookingGetBookingStatusErrors, stats.BookingGetBookingStatusErrors+stats.BookingGetBookingStatusSuccess)
	}
	if config.BookingRescheduleFlow || config.BookingAllFlows {
		if stats.BookingReschedulingSuccess {
			logger.Println("Rescheduling Succeeded")
		} else {
			totalErrors++
			logger.Println("Rescheduling Failed")
		}
	}

	logger.Println("\n\n\n")
	if totalErrors == 0 {
		logger.Println("All Tests Pass!")
	} else {
		logger.Printf("Found %d Errors", totalErrors)
	}

	logger.Println("\n************* End Stats *************\n")
}

// RunTests runs booking tests.
func RunTests(ctx context.Context, logger *log.Logger, config *utils.Config, av []*fpb.Availability, avForRescheduling []*fpb.Availability, stats *utils.TestSummary) {
	conn := config.Conn
	var slots = av
	// HealthCheck Flow
	if config.BookingHealthFlow || config.BookingAllFlows {
		stats.BookingHealthCheckSuccess = true
		if err := api.HealthCheck(ctx, logger, conn); err != nil {
			stats.BookingHealthCheckSuccess = false
			logger.Println(err.Error())
		}
		stats.BookingHealthCheckCompleted = true
		if !config.BookingAllFlows && !config.BookingCheckFlow && !config.BookingBookFlow &&
			!config.BookingListFlow && !config.BookingStatusFlow && !config.BookingRescheduleFlow {
			logStats(stats, logger, config)
			return
		}
	}
	if config.BookingCheckFlow || config.BookingAllFlows {
		slots = nil
		if config.BookingUseBal {
			utils.LogFlow(logger, "Batch Availability Lookup", "Start")
			for _, a := range utils.SplitAvailabilityByMerchant(av) {
				if avSlots, err := api.AvailableSlotsFromBAL(ctx, logger, a, conn); err != nil {
					logger.Printf("BatchAvailabilityLookup returned error: %v", err)
					stats.BookingBatchAvailabilityLookupErrors++
				} else {
					// Only test CreateBooking on available slots.
					slots = append(slots, avSlots...)
					stats.BookingBatchAvailabilityLookupSuccess++
				}
			}
			utils.LogFlow(logger, "Batch Availability Lookup", "End")
			stats.BookingBatchAvailabilityLookupCompleted = true
		} else {
			// AvailabilityCheck Flow
			utils.LogFlow(logger, "Availability Check", "Start")
			totalSlots := len(av)

			for i, a := range av {
				if err := api.CheckAvailability(ctx, logger, a, conn); err != nil {
					logger.Printf("%s. skipping slot %d/%d", err.Error(), i, totalSlots)
					stats.BookingCheckAvailabilityErrors++
					continue
				}
				// Only test CreateBooking on available slots.
				slots = append(slots, a)
				stats.BookingCheckAvailabilitySuccess++
			}
			utils.LogFlow(logger, "Availability Check", "End")
			stats.BookingCheckAvailabilityCompleted = true
		}
	}

	// CreateBooking Flow.
	var b []*mpb.Booking
	if config.BookingBookFlow || config.BookingAllFlows {
		utils.LogFlow(logger, "Booking", "Start")
		totalSlots := len(slots)
		logger.Printf("total slots %d", totalSlots)
		for i, a := range slots {
			logger.Printf("creating booking")
			booking, err := api.CreateBooking(ctx, logger, a, conn)
			if err != nil {
				logger.Printf("%s. skipping slot %d/%d", err.Error(), i, totalSlots)
				stats.BookingCreateBookingErrors++
				continue
			}
			b = append(b, booking)
			stats.BookingCreateBookingSuccess++
		}
		utils.LogFlow(logger, "Booking", "End")
		stats.BookingCreateBookingCompleted = true
	}
	// ListBookings Flow
	if config.BookingListFlow || config.BookingAllFlows || config.BookingCancelAllBookings {
		if len(b) == 0 && !config.BookingCancelAllBookings {
			b = GenerateBookings(ctx, logger, slots, stats, conn, config)
		}
		utils.LogFlow(logger, "List Bookings", "Start")
		if len(b) > 0 || config.BookingCancelAllBookings {
			var err error
			b, err = api.ListBookings(ctx, logger, b, conn)
			stats.BookingListBookingsSuccess = true
			if err != nil {
				stats.BookingListBookingsSuccess = false
				logger.Println(err.Error())
			}
		} else {
			logger.Println("Could not create bookings to test ListBookings flow with.")
			stats.BookingListBookingsSuccess = false
		}
		utils.LogFlow(logger, "List Bookings", "End")
		stats.BookingListBookingsCompleted = true
	}

	// GetBookingStatus Flow
	if config.BookingStatusFlow || config.BookingAllFlows {
		if len(b) == 0 {
			b = GenerateBookings(ctx, logger, slots, stats, conn, config)
		}

		utils.LogFlow(logger, "BookingStatus", "Start")
		totalBookings := len(b)

		if totalBookings > 0 {
			j := 0
			for i, booking := range b {
				if err := api.GetBookingStatus(ctx, logger, booking, conn); err != nil {
					logger.Printf("%s. abandoning booking %d/%d", err.Error(), i, totalBookings)
					stats.BookingGetBookingStatusErrors++
					continue
				}
				stats.BookingGetBookingStatusSuccess++
				b[j] = booking
				j++
			}
			b = b[:j]
		} else {
			logger.Println("Could not create bookings to test GetBookingStatus flow with.")
		}
		utils.LogFlow(logger, "BookingStatus", "End")
		stats.BookingGetBookingStatusCompleted = true
	}
	// CancelBooking Flow
	if len(b) > 0 {
		utils.LogFlow(logger, "Cancel Booking", "Start")
		for i, booking := range b {
			if err := api.CancelBooking(ctx, logger, booking.GetBookingId(), conn); err != nil {
				logger.Printf("%s. abandoning booking %d/%d", err.Error(), i, len(b))
				stats.BookingCancelBookingsErrors++
				continue
			}
			stats.BookingCancelBookingsSuccess++
		}
		utils.LogFlow(logger, "Cancel Booking", "End")
		stats.BookingCancelBookingsCompleted = true
	}

	// Rescheduling is nuanced and can be isolated
	// from the rest of the tests.
	if config.BookingRescheduleFlow || config.BookingAllFlows {
		utils.LogFlow(logger, "Rescheduling", "Start")
		stats.BookingReschedulingSuccess = true
		if err := api.Rescheduling(ctx, logger, avForRescheduling, conn); err != nil {
			logger.Println(err.Error())
			stats.BookingReschedulingSuccess = false
		}
		utils.LogFlow(logger, "Rescheduling", "End")
		stats.BookingReschedulingCompleted = true
	}

	logStats(stats, logger, config)
}
