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

import (
	"context"
	"log"

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

func logStats(stats *utils.TestSummary, logger *log.Logger, config *utils.Config) {
	logger.Println("\n************* Begin Stats *************\n")
	var totalErrors int
	if config.OrderHealthFlow || config.OrderAllFlows {
		if stats.OrderHealthCheckSuccess {
			logger.Println("HealthCheck Succeeded")
		} else {
			totalErrors++
			logger.Println("HealthCheck Failed")
		}
		stats.OrderHealthCheckCompleted = true
	}
	if config.OrderCheckFlow || config.OrderAllFlows {
		totalErrors += stats.OrderCheckOrderFulfillabilityErrors
		logger.Printf("CheckOrderFulfillability Errors: %d/%d", stats.OrderCheckOrderFulfillabilityErrors, stats.OrderCheckOrderFulfillabilityErrors+stats.OrderCheckOrderFulfillabilitySuccess)
	}
	if config.OrderOrderFlow || config.OrderAllFlows {
		totalErrors += stats.OrderCreateOrderErrors
		logger.Printf("CreateOrder Errors: %d/%d", stats.OrderCreateOrderErrors, stats.OrderCreateOrderErrors+stats.OrderCreateOrderSuccess)
	}
	if config.OrderAllFlows {
		if stats.OrderListOrdersSuccess {
			logger.Println("ListOrders Succeeded")
		} else {
			totalErrors++
			logger.Println("ListOrders Failed")
		}
	}
	if config.OrderCheckFlow || config.OrderOrderFlow || config.OrderAllFlows {
		logger.Printf("Total Slots Processed: %d", stats.OrderTotalSlotsProcessed)
	}

	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 order tests.
func RunTests(ctx context.Context, logger *log.Logger, config *utils.Config, av []*fpb.Availability, services []*fpb.Service, stats *utils.TestSummary) {
	conn := config.Conn
	// HealthCheck Flow
	if config.OrderHealthFlow || config.OrderAllFlows {
		stats.OrderHealthCheckSuccess = true
		if err := api.HealthCheck(ctx, logger, conn); err != nil {
			stats.OrderHealthCheckSuccess = false
			logger.Println(err.Error())
		}
		stats.OrderHealthCheckCompleted = true
		if !config.OrderAllFlows && !config.OrderCheckFlow && !config.OrderOrderFlow {
			logStats(stats, logger, config)
			return
		}
	}
	testInventory, err := utils.BuildLineItemMap(services, av)
	if err != nil {
		logger.Printf("Remaining tests cannot run due to error building line items: %s\n", err)
		return
	}

	// CheckOrderFulfillability Flow
	if config.OrderCheckFlow || config.OrderAllFlows {
		utils.LogFlow(logger, "CheckOrderFulfillability", "Start")
		for _, value := range testInventory {
			stats.OrderTotalSlotsProcessed += len(value)
		}

		i := 0
		for merchantID, lineItems := range testInventory {
			if err := api.CheckOrderFulfillability(ctx, logger, merchantID, lineItems, conn); err != nil {
				logger.Printf("%s. skipping slots %d-%d/%d", err.Error(), i, i+len(lineItems)-1, stats.OrderTotalSlotsProcessed)
				stats.OrderCheckOrderFulfillabilityErrors += len(lineItems)
				delete(testInventory, merchantID)
				i += len(lineItems)
				continue
			}
			stats.OrderCheckOrderFulfillabilitySuccess += len(lineItems)
			i += len(lineItems)
		}
		stats.OrderCheckOrderFulfillabilityCompleted = true
		utils.LogFlow(logger, "CheckOrderFulfillability", "End")
	}
	// CreateOrder Flow.
	var orders []*mpb.Order
	if config.OrderOrderFlow || config.OrderAllFlows {
		utils.LogFlow(logger, "CreateOrder", "Start")
		if stats.OrderTotalSlotsProcessed == 0 {
			for _, value := range testInventory {
				stats.OrderTotalSlotsProcessed += len(value)
			}
		}

		i := 0
		for merchantID, lineItems := range testInventory {
			order, err := api.CreateOrder(ctx, logger, merchantID, lineItems, conn)
			if err != nil {
				logger.Printf("%s. skipping slot %d-%d/%d", err.Error(), i, i+len(lineItems)-1, stats.OrderTotalSlotsProcessed)
				stats.OrderCreateOrderErrors += len(lineItems)
				delete(testInventory, merchantID)
				i += len(lineItems)
				continue
			}
			orders = append(orders, order)
			stats.OrderCreateOrderSuccess += len(lineItems)
			i += len(lineItems)
		}
		stats.OrderCreateOrderCompleted = true
		utils.LogFlow(logger, "CreateOrder", "End")
	}
	// ListOrders Flow
	if config.OrderAllFlows || config.OrderListFlow {
		utils.LogFlow(logger, "ListOrders", "Start")
		stats.OrderListOrdersSuccess = true
		if err := api.ListOrders(ctx, logger, orders, conn); err != nil {
			stats.OrderListOrdersSuccess = false
			logger.Println(err.Error())
		}
		stats.OrderListOrdersCompleted = true
		utils.LogFlow(logger, "ListOrders", "End")
	}
	logStats(stats, logger, config)
}
