/*
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 main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"time"

	"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"
)

const logFile = "http_test_client_log_"

var (
	serverAddr        = flag.String("server_addr", "example.com:80", "Your http server's address in the format of host:port")
	credentialsFile   = flag.String("credentials_file", "", "File containing credentials for your server. Leave blank to bypass authentication. File should have exactly one line of the form 'username:password'.")
	testSlots         = flag.Int("num_test_slots", 10, "Maximum number of slots to test from availability_feed. Slots will be selected randomly")
	allFlows          = flag.Bool("all_tests", false, "Whether to test all endpoints.")
	healthFlow        = flag.Bool("health_check_test", false, "Whether to test the Health endpoint.")
	checkFlow         = flag.Bool("check_availability_test", false, "Whether to test the CheckAvailability endpoint.")
	bookFlow          = flag.Bool("booking_test", false, "Whether to test the CreateBooking endpoint.")
	listFlow          = flag.Bool("list_bookings_test", false, "Whether to test the ListBookings endpoint")
	statusFlow        = flag.Bool("booking_status_test", false, "Whether to test the GetBookingStatus endpoint.")
	rescheduleFlow    = flag.Bool("rescheduling_test", false, "Whether to test the UpdateBooking endpoint.")
	cancelAllBookings = flag.Bool("cancel_all_bookings", false, "This option assumes that the ListBookings and UpdateBooking endpoints are fully functional. This is a convenience flag for purging your system of all previously created bookings.")
	availabilityFeed  = flag.String("availability_feed", "", "Absolute path to availability feed required for all tests except health. Feeds can be in either json or pb3 format")
	outputDir         = flag.String("output_dir", "", "Absolute path of dir to dump log file.")
	caFile            = flag.String("ca_file", "", "Absolute path to your server's Certificate Authority root cert. Downloading all roots currently recommended by the Google Internet Authority is a suitable alternative https://pki.google.com/roots.pem. Leave blank to connect using http rather than https.")
	fullServerName    = flag.String("full_server_name", "", "Fully qualified domain name. Same name used to sign CN. Only necessary if ca_file is specified and the base URL differs from the server address.")
	outputToTerminal  = flag.Bool("output_to_terminal", false, "Output to terminal rather than a file.")
	useBal            = flag.Bool("use_batch_availability_lookup", false, "Whether to use the BatchAvailabilityLookup RPC (as opposed to the deprecated CheckAvailability)")
)

type counters struct {
	TotalSlotsProcessed            int
	HealthCheckSuccess             bool
	BatchAvailabilityLookupErrors  int
	BatchAvailabilityLookupSuccess int
	CheckAvailabilitySuccess       int
	CheckAvailabilityErrors        int
	CreateBookingSuccess           int
	CreateBookingErrors            int
	ListBookingsSuccess            bool
	GetBookingStatusSuccess        int
	GetBookingStatusErrors         int
	CancelBookingsSuccess          int
	CancelBookingsErrors           int
	ReschedulingSuccess            bool
}

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

	var out api.Bookings
	totalSlots := len(av)
	for i, a := range av {
		if *useBal {
			if err := api.BatchAvailabilityLookup([]*fpb.Availability{a}, conn); err != nil {
				log.Printf("BAL error: %s. skipping slot %d/%d", err.Error(), i, totalSlots)
				stats.BatchAvailabilityLookupErrors++
				continue
			}
			stats.BatchAvailabilityLookupSuccess++
		} else {
			if err := api.CheckAvailability(a, conn); err != nil {
				log.Printf("%s. skipping slot %d/%d", err.Error(), i, totalSlots)
				stats.CheckAvailabilityErrors++
				continue
			}
			stats.CheckAvailabilitySuccess++
		}

		booking, err := api.CreateBooking(a, conn)
		if err != nil {
			log.Printf("%s. skipping slot %d/%d", err.Error(), i, totalSlots)
			stats.CreateBookingErrors++
			continue
		}
		out = append(out, booking)
		stats.CreateBookingSuccess++
	}
	return out
}

func createLogFile() (*os.File, error) {
	var err error
	outPath := *outputDir
	if outPath == "" {
		outPath, err = os.Getwd()
		if err != nil {
			return nil, err
		}
	}

	now := time.Now().UTC()
	nowString := fmt.Sprintf("%d-%02d-%02d_%02d-%02d-%02d", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second())
	outFile := filepath.Join(outPath, fmt.Sprintf("%s%s", logFile, nowString))

	return os.Create(outFile)
}

func logStats(stats counters) {
	log.Println("\n************* Begin Stats *************\n")
	var totalErrors int
	if *healthFlow || *allFlows {
		if stats.HealthCheckSuccess {
			log.Println("HealthCheck Succeeded")
		} else {
			totalErrors++
			log.Println("HealthCheck Failed")
		}
	}
	if *useBal {
		totalErrors += stats.BatchAvailabilityLookupErrors
		log.Printf("BatchAvailabilityLookup Errors: %d/%d", stats.BatchAvailabilityLookupErrors, stats.BatchAvailabilityLookupErrors+stats.BatchAvailabilityLookupSuccess)
	} else if *checkFlow || *allFlows {
		totalErrors += stats.CheckAvailabilityErrors
		log.Printf("CheckAvailability Errors: %d/%d", stats.CheckAvailabilityErrors, stats.CheckAvailabilityErrors+stats.CheckAvailabilitySuccess)
	}
	if *bookFlow || *allFlows {
		totalErrors += stats.CreateBookingErrors
		log.Printf("CreateBooking Errors: %d/%d", stats.CreateBookingErrors, stats.CreateBookingErrors+stats.CreateBookingSuccess)
	}
	if *listFlow || *allFlows || *cancelAllBookings {
		if stats.ListBookingsSuccess {
			log.Println("ListBookings Succeeded")
		} else {
			totalErrors++
			log.Println("ListBookings Failed")
		}
	}
	if *statusFlow || *allFlows {
		totalErrors += stats.GetBookingStatusErrors
		log.Printf("GetBookingStatus Errors: %d/%d", stats.GetBookingStatusErrors, stats.GetBookingStatusErrors+stats.GetBookingStatusSuccess)
	}
	if *rescheduleFlow || *allFlows {
		if stats.ReschedulingSuccess {
			log.Println("Rescheduling Succeeded")
		} else {
			totalErrors++
			log.Println("Rescheduling Failed")
		}
	}

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

	log.Println("\n************* End Stats *************\n")
	os.Exit(totalErrors)
}

func main() {
	flag.Parse()
	var stats counters

	if !*outputToTerminal {
		// Set up logging before continuing with flows
		f, err := createLogFile()
		if err != nil {
			log.Fatalf("Failed to create log file %v", err)
		}
		defer f.Close()
		log.SetOutput(f)
	}

	conn, err := api.InitHTTPConnection(*serverAddr, *credentialsFile, *caFile, *fullServerName)
	if err != nil {
		log.Fatalf("Failed to init http connection %v", err)
	}

	// Health check doesn't affect the cancel booking flow so we let it through.
	if *cancelAllBookings && (*allFlows || *checkFlow || *bookFlow || *listFlow || *statusFlow || *rescheduleFlow) {
		log.Fatal("cancel_all_bookings is not supported with other test flows")
	}

	// HealthCheck Flow
	if *healthFlow || *allFlows {
		stats.HealthCheckSuccess = true
		if err := api.HealthCheck(conn); err != nil {
			stats.HealthCheckSuccess = false
			log.Println(err.Error())
		}
		if !*allFlows && !*checkFlow && !*bookFlow &&
			!*listFlow && !*statusFlow && !*rescheduleFlow {
			logStats(stats)
		}
	}

	var av []*fpb.Availability
	var avForRescheduling []*fpb.Availability
	if !*cancelAllBookings {
		// Build availablility records.
		if *availabilityFeed == "" {
			log.Fatal("please set availability_feed flag if you wish to test additional flows")
		}
		av, err = utils.AvailabilityFrom(*availabilityFeed, *testSlots, false)
		if err != nil {
			log.Fatalf("Failed to get availability: %v", err.Error())
		}
		stats.TotalSlotsProcessed += len(av)

		avForRescheduling, err = utils.AvailabilityFrom(*availabilityFeed, *testSlots, true)
		if err != nil {
			log.Fatalf("Failed to get availability for rescheduling test: %v", err.Error())
		}
	}

	if *useBal {
		utils.LogFlow("Batch Availability Lookup", "Start")
		for _, a := range utils.SplitAvailabilityByMerchant(av) {
			if err = api.BatchAvailabilityLookup(a, conn); err != nil {
				log.Printf("BatchAvailabilityLookup returned error: %v", err)
				stats.BatchAvailabilityLookupErrors++
			} else {
				stats.BatchAvailabilityLookupSuccess++
			}
		}
		utils.LogFlow("Batch Availability Lookup", "End")
	} else if *checkFlow || *allFlows {
		// AvailabilityCheck Flow
		utils.LogFlow("Availability Check", "Start")
		totalSlots := len(av)

		j := 0
		for i, a := range av {
			if err = api.CheckAvailability(a, conn); err != nil {
				log.Printf("%s. skipping slot %d/%d", err.Error(), i, totalSlots)
				stats.CheckAvailabilityErrors++
				continue
			}
			stats.CheckAvailabilitySuccess++
			av[j] = a
			j++
		}
		av = av[:j]
		utils.LogFlow("Availability Check", "End")
	}
	// CreateBooking Flow.
	var b []*mpb.Booking
	if *bookFlow || *allFlows {
		utils.LogFlow("Booking", "Start")
		totalSlots := len(av)
		for i, a := range av {
			booking, err := api.CreateBooking(a, conn)
			if err != nil {
				log.Printf("%s. skipping slot %d/%d", err.Error(), i, totalSlots)
				stats.CreateBookingErrors++
				continue
			}
			b = append(b, booking)
			stats.CreateBookingSuccess++
		}
		utils.LogFlow("Booking", "End")
	}
	// ListBookings Flow
	if *listFlow || *allFlows || *cancelAllBookings {
		if len(b) == 0 && !*cancelAllBookings {
			b = GenerateBookings(av, &stats, conn)
		}
		utils.LogFlow("List Bookings", "Start")
		b, err = api.ListBookings(b, conn)
		stats.ListBookingsSuccess = true
		if err != nil {
			stats.ListBookingsSuccess = false
			log.Println(err.Error())
		}
		utils.LogFlow("List Bookings", "End")
	}

	// GetBookingStatus Flow
	if *statusFlow || *allFlows {
		if len(b) == 0 {
			b = GenerateBookings(av, &stats, conn)
		}

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

		j := 0
		for i, booking := range b {
			if err = api.GetBookingStatus(booking, conn); err != nil {
				log.Printf("%s. abandoning booking %d/%d", err.Error(), i, totalBookings)
				stats.GetBookingStatusErrors++
				continue
			}
			stats.GetBookingStatusSuccess++
			b[j] = booking
			j++
		}
		b = b[:j]
		utils.LogFlow("BookingStatus", "End")
	}
	// CancelBooking Flow
	if len(b) > 0 {
		utils.LogFlow("Cancel Booking", "Start")
		for i, booking := range b {
			if err = api.CancelBooking(booking.GetBookingId(), conn); err != nil {
				log.Printf("%s. abandoning booking %d/%d", err.Error(), i, len(b))
				stats.CancelBookingsErrors++
				continue
			}
			stats.CancelBookingsSuccess++
		}
		utils.LogFlow("Cancel Booking", "End")
	}

	// Rescheduling is nuanced and can be isolated
	// from the rest of the tests.
	if *rescheduleFlow || *allFlows {
		utils.LogFlow("Rescheduling", "Start")
		stats.ReschedulingSuccess = true
		if err = api.Rescheduling(avForRescheduling, conn); err != nil {
			log.Println(err.Error())
			stats.ReschedulingSuccess = false
		}
		utils.LogFlow("Rescheduling", "End")
	}

	logStats(stats)
}
