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

	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 syncronously, including ListOrders flow.")
	healthFlow       = flag.Bool("health_check_test", false, "Whether to test the Health endpoint.")
	checkFlow        = flag.Bool("check_order_test", false, "Whether to test the CheckOrderFulfillability endpoint.")
	orderFlow        = flag.Bool("create_order_test", false, "Whether to test the CreateOrder endpoint.")
	serviceFeed      = flag.String("service_feed", "", "Absolute path to service feed required for all tests except health. Feeds can be in either json or pb3 format")
	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.")
)

type counters struct {
	TotalSlotsProcessed             int
	HealthCheckSuccess              bool
	CheckOrderFulfillabilitySuccess int
	CheckOrderFulfillabilityErrors  int
	CreateOrderSuccess              int
	CreateOrderErrors               int
	ListOrdersSuccess               bool
}

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 *checkFlow || *allFlows {
		totalErrors += stats.CheckOrderFulfillabilityErrors
		log.Printf("CheckOrderFulfillability Errors: %d/%d", stats.CheckOrderFulfillabilityErrors, stats.CheckOrderFulfillabilityErrors+stats.CheckOrderFulfillabilitySuccess)
	}
	if *orderFlow || *allFlows {
		totalErrors += stats.CreateOrderErrors
		log.Printf("CreateOrder Errors: %d/%d", stats.CreateOrderErrors, stats.CreateOrderErrors+stats.CreateOrderSuccess)
	}
	if *allFlows {
		if stats.ListOrdersSuccess {
			log.Println("ListOrders Succeeded")
		} else {
			totalErrors++
			log.Println("ListOrders Failed")
		}
	}
	if *checkFlow || *orderFlow || *allFlows {
		log.Printf("Total Slots Processed: %d", stats.TotalSlotsProcessed)
	}

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

	// 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 && !*orderFlow {
			logStats(stats)
		}
	}

	if *availabilityFeed == "" || *serviceFeed == "" {
		log.Fatal("please set both availability_feed and service_feed flags")
	}

	testInventory, err := utils.MerchantLineItemMapFrom(*serviceFeed, *availabilityFeed, *testSlots)
	if err != nil {
		log.Fatal(err.Error())
	}

	// CheckOrderFulfillability Flow
	if *checkFlow || *allFlows {
		utils.LogFlow("CheckOrderFulfillability", "Start")
		for _, value := range testInventory {
			stats.TotalSlotsProcessed += len(value)
		}

		i := 0
		for merchantID, lineItems := range testInventory {
			if err = api.CheckOrderFulfillability(merchantID, lineItems, conn); err != nil {
				log.Printf("%s. skipping slots %d-%d/%d", err.Error(), i, i+len(lineItems)-1, stats.TotalSlotsProcessed)
				stats.CheckOrderFulfillabilityErrors += len(lineItems)
				delete(testInventory, merchantID)
				i += len(lineItems)
				continue
			}
			stats.CheckOrderFulfillabilitySuccess += len(lineItems)
			i += len(lineItems)
		}
		utils.LogFlow("CheckOrderFulfillability", "End")
	}
	// CreateOrder Flow.
	var orders []*mpb.Order
	if *orderFlow || *allFlows {
		utils.LogFlow("CreateOrder", "Start")
		if stats.TotalSlotsProcessed == 0 {
			for _, value := range testInventory {
				stats.TotalSlotsProcessed += len(value)
			}
		}

		i := 0
		for merchantID, lineItems := range testInventory {
			order, err := api.CreateOrder(merchantID, lineItems, conn)
			if err != nil {
				log.Printf("%s. skipping slot %d-%d/%d", err.Error(), i, i+len(lineItems)-1, stats.TotalSlotsProcessed)
				stats.CreateOrderErrors += len(lineItems)
				delete(testInventory, merchantID)
				i += len(lineItems)
				continue
			}
			orders = append(orders, order)
			stats.CreateOrderSuccess += len(lineItems)
			i += len(lineItems)
		}
		utils.LogFlow("CreateOrder", "End")
	}
	// ListOrders Flow
	if *allFlows {
		utils.LogFlow("ListOrders", "Start")
		stats.ListOrdersSuccess = true
		if err = api.ListOrders(orders, conn); err != nil {
			stats.ListOrdersSuccess = false
			log.Println(err.Error())
		}
		utils.LogFlow("ListOrders", "End")
	}

	logStats(stats)
}
