/*
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 (
	"crypto/tls"
	"crypto/x509"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"time"

	"github.com/maps-booking/api"
	"github.com/maps-booking/utils"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"

	mpb "github.com/maps-booking/bookingservice"
	fpb "github.com/maps-booking/feeds"
)

const logFile = "grpc_test_client_log_"

/*
Below is a string representation of the client certificate and private key.
This is a self signed cert. To use this cert, maps-booking/certs/root.pem
must be added to your server.

Viewing the contents of this cert in a human readable format can be achieved using openssl.
The command and subsequent output are below for your convenience.

	openssl x509 -in .../maps-booking/certs/test_client_cert.pem -inform pem -noout -text

	Certificate:
			Data:
					Version: 3 (0x2)
					Serial Number: 1 (0x1)
			Signature Algorithm: sha256WithRSAEncryption
					Issuer: C=US, ST=California, L=Mountain View, O=Internet Widgits Pty Ltd, CN=maps-booking_test-client
					Validity
							Not Before: Oct 27 01:53:28 2017 GMT
							Not After : Oct 25 01:53:28 2027 GMT
					Subject: C=US, ST=California, O=Internet Widgits Pty Ltd, CN=maps-booking_test-client-cert
*/
const clientCert = `-----BEGIN CERTIFICATE-----
MIIE5DCCAsygAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx
EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxITAf
BgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEhMB8GA1UEAwwYbWFwcy1i
b29raW5nX3Rlc3QtY2xpZW50MB4XDTE3MTAyNzAxNTMyOFoXDTI3MTAyNTAxNTMy
OFowbTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEmMCQGA1UEAwwdbWFwcy1ib29raW5n
X3Rlc3QtY2xpZW50LWNlcnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQC4SoqntW+syzjdw5an2HkP4ZobuUr/i9eTZ5ub/JpHnKHE/xpAFAI3Pii7b4mv
ZlbEazRsKJc0LQ+3hblBQdwBxF/QPElH10fD5uhScOOpLz5M9wlX+cDLSrXhDiKM
9xPY9OlpydIUu/FbU8V+gIsibruCOUB92aMKTkZMwgMRbPIBHF4IsLODm2JQiyFF
EbJje3mVmQtHyLoWCwWU75wtIgFt7WheTSEw2IpotZTT3nQCqhhrYvUvcwYnj7CD
/18n7ClA/7nf3+f+1WkZX6GITvXEe3A8Rj0oes/cZlzZO0aVxmosnAQiIt2LWuis
Lrs//lQEhAl/rRl1ZHoE+LOLAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4
QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBSK
90Bvc8jEeKuD4ZgUak0QCi5byjAfBgNVHSMEGDAWgBSwnp+00yr82MUrKAIkoVMT
WtzoozANBgkqhkiG9w0BAQsFAAOCAgEAtJoFY0TVZP4SwnLaX6hBEbv3CvIhL/08
WSce1e48XKZCWnL+NmxFJu102QSWjXwpF1XsCEOUjhEWsOfmLQ0/z5Pieqsj9cfx
vfH8Q8BZkC9shykQrO0Hg/Ip+VsU3KSpkpehj0cfUuPuMFZWmPouZGnpyTMXGx/C
L7SeqBBPa3TlSpONr5IVrI0j4Agfv0+qga7DfQUY6jsxx8uVxl6jbpFBx7UXekTa
aIP+Wqq0H9x/yWYt+K6yWmb5THAx/pTNOUYGFiFnW56fUap1UgPEF0vNZHHYZycD
hePsd9jlomD3G38tBmM5qd5CH3OH9S2U2CnC1ifDP6DxxlNHPFCxk6YrISu5fEly
+kcbf3PNKJlqtIL4/GRYsD1e0eVNTMEh5i+qgGnEoErVnlDTM+xolf1DJzSA3uNO
P6HccNGDcV4TePvQ9KU3ACMtBCNBbLqQm1r7e8U6MzDmAUOXhDvXMv7pdLFNiJvd
uD/faRnhAt9AsRCz1HjYx7aNz5jpB7uZCrDlDmuFGxG8ieInQMrATUz+E8Yfzh/d
5k5U0jOgR+IjPKpaq6Z4ejwg4i9vW7EJ8o+Nk1oMB0IMjAJi/UOZl9zRANvcVxO5
T8dmsxdWt/l68bdjP+jY1vjQ98ebTfo+q1cTNDoO0nDJHOw/NDemxTPgUa1Rs5vK
5c2Q8YXBTiU=
-----END CERTIFICATE-----`
const clientKey = `-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAuEqKp7VvrMs43cOWp9h5D+GaG7lK/4vXk2ebm/yaR5yhxP8a
QBQCNz4ou2+Jr2ZWxGs0bCiXNC0Pt4W5QUHcAcRf0DxJR9dHw+boUnDjqS8+TPcJ
V/nAy0q14Q4ijPcT2PTpacnSFLvxW1PFfoCLIm67gjlAfdmjCk5GTMIDEWzyARxe
CLCzg5tiUIshRRGyY3t5lZkLR8i6FgsFlO+cLSIBbe1oXk0hMNiKaLWU0950AqoY
a2L1L3MGJ4+wg/9fJ+wpQP+539/n/tVpGV+hiE71xHtwPEY9KHrP3GZc2TtGlcZq
LJwEIiLdi1rorC67P/5UBIQJf60ZdWR6BPiziwIDAQABAoIBAQCbJy6ayTauzB0h
HxSMVMR/aVj8NEB+6rXgxN6OMdmVprnPB1KLVg0Tg0J5owrQ36D3FqZ41KeP5swP
nwZ7eT4HQtPDla3ATO9/b7xyA9a3Ti3uUCDOr1bwEAMV6XePJEjSZEbKqH40tJIb
aGih+wioQX+dwCOakIsiFwo6fzBkDtsj4V3qVunuZ5TRufUSrXebAMSsE5U+POch
FznfqsD/vhus5ggbhM/8wG1NgEtO5apkc+KjA/vnWpcpSeWxnBYmQZr0dU9iZJr+
vCxMKY+kdVfjohbeGQt51TqUkBdLbfUlun8fE1X9hrsA5aYonP82unJ+hWn3Wg60
fP9vr1gBAoGBAPWcsKoCG6DisgLAjNhAMC2Q7lp2qsM7Y01p4epLX8UxOHRMlpnr
erNRc4k75hZDp7/rtrO6eb3F+76mlPVbqi/JRRqY5xM8vsDF8KYSAW8XJXZ6AP+Z
G7sxjJ8QnlT1lAWK+XNxAEk6U3jj6eB+CfGSZJJh3tbjhX69BseE5uQBAoGBAMAV
6cpOq+F0ZSlh3sljvlDEPY0BaUtlAF5LOX6Vdg7c/zeWJtAAE24hPYwxSi9e4jYx
eHBM3Xk5yQVGsIbxl/dvgWGY2nbzb1YdbOEEzrVBh7hm8YW3DER+HwNcDpMhoWCf
O8uD59YNsyvrqD/vb7KpVDWr+yD8ClO7zjLL3ueLAoGAdAZMElOil5LfgptRLYrM
94mCf2uVaVqxo01EcnieyjlhMNdJQXbS5Miyan7IR3Y4VVpVWXvarMJNFRf+QBXI
RICwy0q1xgmpFsmqz9iror3tbZVeyV+bkQdsJWwlT38fKKspAda8ytrpua74uZrw
uZRtPBVNvneGhYNoI3Jt3AECgYB5bGDBdkHI3x8jra57eAXSYHrYK9A3zL0S3lKV
5j0e4CylItGeIq4lq/WQLYhLsZslztfnhW9rNlAQecMVSptZ2q7a1xkioHf849Tz
2Wohwi7dLpX2hOPIWEGaihLchyHQRlgyKkvfUAG2/dz5rY3aTpfg5bp1+1072Thb
e+yISQKBgGgtchLhw26f+wIvDDJx6AExEbbnV5V84riqZR4PpBz4e88xWdtpfYT7
J0nidjfbgcpfIysD8ELn/bGtNsYWrTkX8rqB5buBGf+WP7+ChWLwdm1GPtYJJN4s
ewhN35RpB6EjTdp9jp5ifTfSSBAoHN8yJeeHxU64HHb8nDdBwxmW
-----END RSA PRIVATE KEY-----`

var (
	serverAddr       = flag.String("server_addr", "example.com:80", "Your grpc server's address in the format of host:port")
	rpcTimeout       = flag.Duration("rpc_timeout", 30*time.Second, "Number of seconds to wait before abandoning request")
	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.")
	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.")
	enableTLS        = flag.Bool("tls", false, "Whether to enable TLS when using the test client. Please review the README.md before attempting to use this flag.")
	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")
	serverName       = flag.String("servername_override", "", "Override FQDN to use. Please see README for additional details")
)

type counters struct {
	TotalSlotsProcessed      int
	HealthCheckSuccess       bool
	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(ctx context.Context, av []*fpb.Availability, stats *counters, c mpb.BookingServiceClient) 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 err := api.CheckAvailability(ctx, a, c); err != nil {
			log.Printf("%s. skipping slot %d/%d", err.Error(), i, totalSlots)
			stats.CheckAvailabilityErrors++
			continue
		}
		stats.CheckAvailabilitySuccess++

		booking, err := api.CreateBooking(ctx, a, c)
		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 setTimeout(ctx context.Context) context.Context {
	tCtx, _ := context.WithTimeout(ctx, *rpcTimeout)
	return tCtx
}

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

func buildGrpcConnection() (*grpc.ClientConn, error) {
	var opts []grpc.DialOption
	if *enableTLS {
		cert, err := tls.X509KeyPair([]byte(clientCert), []byte(clientKey))
		if err != nil {
			return nil, err
		}
		b, err := ioutil.ReadFile(*caFile)
		if err != nil {
			return nil, fmt.Errorf("failed to read root certificates file: %v", err)
		}
		cp := x509.NewCertPool()
		if !cp.AppendCertsFromPEM(b) {
			return nil, errors.New("failed to parse root certificates, please check your roots file (ca_file flag) and try again")
		}
		config := &tls.Config{Certificates: []tls.Certificate{cert}, RootCAs: cp}
		if *serverName != "" {
			config.ServerName = *serverName
		}
		creds := credentials.NewTLS(config)
		opts = append(opts, grpc.WithTransportCredentials(creds))
	} else {
		opts = append(opts, grpc.WithInsecure())
	}
	return grpc.Dial(*serverAddr, opts...)
}

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 := buildGrpcConnection()
	if err != nil {
		log.Fatalf("failed to dial: %v", err)
	}
	defer conn.Close()
	client := mpb.NewBookingServiceClient(conn)

	ctx := context.Background()

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

	// 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)
	if err != nil {
		log.Fatal(err.Error())
	}
	stats.TotalSlotsProcessed += len(av)

	// AvailabilityCheck Flow
	if *checkFlow || *allFlows {
		utils.LogFlow("Availability Check", "Start")
		totalSlots := len(av)

		j := 0
		for i, a := range av {
			if err = api.CheckAvailability(setTimeout(ctx), a, client); 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(setTimeout(ctx), a, client)
			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 {
		if len(b) == 0 {
			b = GenerateBookings(setTimeout(ctx), av, &stats, client)
		}
		utils.LogFlow("List Bookings", "Start")
		b, err = api.ListBookings(setTimeout(ctx), b, client)
		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(setTimeout(ctx), av, &stats, client)
		}

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

		j := 0
		for i, booking := range b {
			if err = api.GetBookingStatus(setTimeout(ctx), booking, client); 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(setTimeout(ctx), booking, client); 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(setTimeout(ctx), av, client); err != nil {
			log.Println(err.Error())
			stats.ReschedulingSuccess = false
		}
		utils.LogFlow("Rescheduling", "End")
	}

	logStats(stats)
}
