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

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

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

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