/*
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
	if *useBal {
		if err := api.BatchAvailabilityLookup(av, conn); err != nil {
			log.Printf("BatchAvailabilityLookup returned error: %v", err)
			stats.BatchAvailabilityLookupErrors++
			return out
		}
		stats.BatchAvailabilityLookupSuccess++
	}

	totalSlots := len(av)
	for i, a := range av {
		if !*useBal {
			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")
		if err := api.BatchAvailabilityLookup(av, 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)
}
