package server

/*
   Utilities for creating GCE instances to run servers.
*/

import (
	"context"
	"flag"
	"fmt"
	"sort"

	"go.skia.org/infra/go/auth"
	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/gce"
	"go.skia.org/infra/go/sklog"
)

var (
	// Flags.
	instance       = flag.String("instance", "", "Which instance to create/delete.")
	create         = flag.Bool("create", false, "Create the instance. Either --create or --delete is required.")
	delete         = flag.Bool("delete", false, "Delete the instance. Either --create or --delete is required.")
	deleteDataDisk = flag.Bool("delete-data-disk", false, "Delete the data disk. Only valid with --delete")
	ignoreExists   = flag.Bool("ignore-exists", false, "Do not fail out when creating a resource which already exists or deleting a resource which does not exist.")
	listContacts   = flag.Bool("list-contacts", false, "List contacts for each instance and exit.")
)

// Base config for server instances.
func Server20170928(name string) *gce.Instance {
	return &gce.Instance{
		BootDisk: &gce.Disk{
			Name:        name,
			SourceImage: "skia-pushable-base-v2017-09-28-000",
			Type:        gce.DISK_TYPE_PERSISTENT_STANDARD,
		},
		DataDisks: []*gce.Disk{{
			Name:      fmt.Sprintf("%s-data", name),
			MountPath: gce.DISK_MOUNT_PATH_DEFAULT,
			SizeGb:    300,
			Type:      gce.DISK_TYPE_PERSISTENT_STANDARD,
		}},
		MachineType:       gce.MACHINE_TYPE_HIGHMEM_16,
		Metadata:          map[string]string{},
		MetadataDownloads: map[string]string{},
		Name:              name,
		Os:                gce.OS_LINUX,
		Scopes: []string{
			auth.SCOPE_FULL_CONTROL,
			auth.SCOPE_GERRIT,
			auth.SCOPE_PUBSUB,
			auth.SCOPE_USERINFO_EMAIL,
			auth.SCOPE_USERINFO_PROFILE,
		},
		ServiceAccount: gce.SERVICE_ACCOUNT_DEFAULT,
		Tags:           []string{"http-server", "https-server"},
		User:           gce.USER_DEFAULT,
	}
}

// Main takes a map of string -> gce.Instance to initialize in the given zone.
// The string keys are nicknames for the instances (e.g. "prod", "staging").
//  Only the instance specified by the --instance flag will be created.
func Main(zone string, instances map[string]*gce.Instance) {
	common.Init()

	if *listContacts {
		for instance, vm := range instances {
			fmt.Println(instance + ":")
			for _, contact := range vm.Contacts {
				fmt.Println("\t" + contact)
			}
		}
		return
	}

	vm, ok := instances[*instance]
	if !ok {
		validInstances := make([]string, 0, len(instances))
		for k := range instances {
			validInstances = append(validInstances, k)
		}
		sort.Strings(validInstances)
		sklog.Fatalf("Invalid --instance %q; name must be one of: %v", *instance, validInstances)
	}
	if *create == *delete {
		sklog.Fatal("Please specify --create or --delete, but not both.")
	}

	// Create the GCloud object.
	g, err := gce.NewLocalGCloud(gce.PROJECT_ID_SERVER, zone)
	if err != nil {
		sklog.Fatal(err)
	}
	if err := g.CheckSsh(); err != nil {
		sklog.Fatal(err)
	}

	// Perform the requested operation.
	if *create {
		if err := g.CreateAndSetup(context.Background(), vm, *ignoreExists); err != nil {
			sklog.Fatal(err)
		}
	} else {
		if err := g.Delete(vm, *ignoreExists, *deleteDataDisk); err != nil {
			sklog.Fatal(err)
		}
	}
}
