package main

/*
	Read and validate an AutoRoll config file.
*/

import (
	"context"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"path/filepath"

	"go.skia.org/infra/autoroll/go/config"
	"go.skia.org/infra/go/skerr"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/util"
	"go.skia.org/infra/task_driver/go/lib/os_steps"
	"go.skia.org/infra/task_driver/go/td"
	"google.golang.org/protobuf/encoding/prototext"
)

var (
	// Required properties for this task.
	projectId  = flag.String("project_id", "", "ID of the Google Cloud project.")
	taskId     = flag.String("task_id", "", "ID of this task.")
	taskName   = flag.String("task_name", "", "Name of the task.")
	workdir    = flag.String("workdir", ".", "Working directory")
	configFlag = flag.String("config", "", "Config file or dir of config files to validate.")

	// Optional flags.
	local  = flag.Bool("local", false, "True if running locally (as opposed to on the bots)")
	output = flag.String("o", "", "If provided, dump a JSON blob of step data to the given file. Prints to stdout if '-' is given.")
)

var (
	// "constants"
	chromiumServiceAccounts = []string{
		"chromium-autoroll@skia-public.iam.gserviceaccount.com",
		"chromium-release-autoroll@skia-public.iam.gserviceaccount.com",
		"chromium-internal-autoroll@skia-corp.google.com.iam.gserviceaccount.com",
	}
)

func validateConfig(ctx context.Context, f string) (string, error) {
	var rollerName string
	return rollerName, td.Do(ctx, td.Props(fmt.Sprintf("Validate %s", f)), func(ctx context.Context) error {
		// Decode the config.
		var cfg config.Config
		if err := util.WithReadFile(f, func(f io.Reader) error {
			b, err := ioutil.ReadAll(f)
			if err != nil {
				return skerr.Wrap(err)
			}
			if err := prototext.Unmarshal(b, &cfg); err != nil {
				return skerr.Wrap(err)
			}
			return nil
		}); err != nil {
			td.Fatalf(ctx, "%s failed validation: %s", f, err)
		}

		// Validate the config.
		if err := cfg.Validate(); err != nil {
			return skerr.Wrap(err)
		}
		if util.In(cfg.ServiceAccount, chromiumServiceAccounts) {
			gerrit := cfg.GetGerrit()
			if gerrit != nil && gerrit.Config == config.GerritConfig_CHROMIUM {
				if gerrit.Project != "emscripten-releases" && gerrit.Project != "infra/infra" {
					return skerr.Fmt("Chromium rollers must use Gerrit config CHROMIUM_BOT_COMMIT")
				}
			}
		}

		rollerName = cfg.RollerName
		return nil
	})
}

func main() {
	// Setup.
	ctx := td.StartRun(projectId, taskId, taskName, output, local)
	defer td.EndRun(ctx)

	if *configFlag == "" {
		td.Fatalf(ctx, "--config is required.")
	}

	// Gather files to validate.
	configFiles := []string{}
	f, err := os_steps.Stat(ctx, *configFlag)
	if err != nil {
		td.Fatal(ctx, err)
	}
	if f.IsDir() {
		files, err := os_steps.ReadDir(ctx, *configFlag)
		if err != nil {
			td.Fatal(ctx, err)
		}
		for _, f := range files {
			// Ignore subdirectories and file names starting with '.'
			if !f.IsDir() && f.Name()[0] != '.' {
				configFiles = append(configFiles, filepath.Join(*configFlag, f.Name()))
			}
		}
	} else {
		configFiles = append(configFiles, *configFlag)
	}

	// Validate the file(s).
	rollers := make(map[string]string, len(configFiles))
	for _, f := range configFiles {
		rollerName, err := validateConfig(ctx, f)
		if err != nil {
			td.Fatalf(ctx, "%s failed validation: %s", f, err)
		}
		if otherFile, ok := rollers[rollerName]; ok {
			td.Fatalf(ctx, "Roller %q is defined in both %s and %s", rollerName, f, otherFile)
		}
		rollers[rollerName] = f
	}
	sklog.Infof("Validated %d files.", len(configFiles))
}
