/*
Copyright 2019 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 (
	"context"
	"flag"
	"log"

	"github.com/maps-booking-v3/api"
	fpb "github.com/maps-booking-v3/feeds"
	"github.com/maps-booking-v3/utils"
	"github.com/maps-booking-v3/waitlist"
)

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'.")
	numTestServices           = flag.Int("num_test_services", 10, "Maximum number of services to test from service_feed. Services 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.")
	batchGetWaitEstimatesFlow = flag.Bool("batch_get_wait_estimates_test", false, "Whether to test the BatchGetWaitEstimates endpoint.")
	createWaitlistEntryFlow   = flag.Bool("create_waitlist_entry_test", false, "Whether to test the CreateWaitlistEntry endpoint.")
	getWaitlistEntryFlow      = flag.Bool("get_waitlist_entry_test", false, "Whether to test the GetWaitlistEntry endpoint. CreateWaitlistEntry will also be called to create the entries.")
	deleteWaitlistEntryFlow   = flag.Bool("delete_waitlist_entry_test", false, "Whether to test the DeleteWaitlistEntry endpoint. CreateWaitlistEntry will also be called to create the entries.")
	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.")
	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.")
)

func makeConfig(logger *log.Logger) *utils.Config {
	conn, err := api.InitHTTPConnection(*serverAddr, *credentialsFile, *caFile, *fullServerName)
	if err != nil {
		logger.Fatalf("Failed to init http connection %v", err)
	}
	return &utils.Config{Conn: conn,
		WaitlistAllFlows:                  *allFlows,
		WaitlistHealthFlow:                *healthFlow,
		WaitlistBatchGetWaitEstimatesFlow: *batchGetWaitEstimatesFlow,
		WaitlistCreateWaitlistEntryFlow:   *createWaitlistEntryFlow,
		WaitlistGetWaitlistEntryFlow:      *getWaitlistEntryFlow,
		WaitlistDeleteWaitlistEntryFlow:   *deleteWaitlistEntryFlow,
	}
}

func main() {
	flag.Parse()

	logger, f, err := utils.MakeLogger(*outputToTerminal, *outputDir)
	if err != nil {
		log.Fatal("Could not create logger: ", err)
	}
	if f != nil {
		defer f.Close()
	}
	config := makeConfig(logger)
	var summary utils.TestSummary

	needService := config.WaitlistAllFlows || config.WaitlistBatchGetWaitEstimatesFlow || config.WaitlistCreateWaitlistEntryFlow ||
		config.WaitlistGetWaitlistEntryFlow || config.WaitlistDeleteWaitlistEntryFlow

	// Build services.
	var reducedServices []*fpb.Service
	if needService {
		if *serviceFeed == "" {
			logger.Fatal("please set service_feed flag if you wish to test additional flows")
		}

		var services []*fpb.Service
		services, err = utils.ParseServiceFeed(*serviceFeed)
		if err != nil {
			logger.Fatalf("Failed to get services: %v", err.Error())
		}
		// Remove services without waitlist rules.
		waitlistServices := services[:0]
		for _, s := range services {
			if s.GetWaitlistRules() != nil {
				waitlistServices = append(waitlistServices, s)
			}
		}

		if len(waitlistServices) == 0 {
			logger.Fatal("no services have waitlist rules")
		}
		reducedServices = utils.ReduceServices(logger, waitlistServices, *numTestServices)
	} else {
		reducedServices = []*fpb.Service{}
	}
	summary.WaitlistTotalServicesProcessed += len(reducedServices)
	waitlist.RunTests(context.Background(), logger, config, reducedServices, &summary)
}
