// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package main

import (
	"context"
	"fmt"
	"log"
	"net/mail"
	"path/filepath"
	"regexp"
	"strings"
	"time"

	"github.com/gorhill/cronexpr"
	"github.com/maruel/subcommands"
	"go.fuchsia.dev/infra/cmd/roller-configurator/proto"
)

func cmdValidate() *subcommands.Command {
	return &subcommands.Command{
		UsageLine: "validate [-config <config-path>]",
		ShortDesc: "Validate a rollers.textproto file.",
		LongDesc:  "Validate a rollers.textproto file.",
		CommandRun: func() subcommands.CommandRun {
			c := &validateRun{}
			c.Init()
			return c
		},
	}
}

type validateRun struct {
	subcommands.CommandRunBase
	configPath string
}

func (c *validateRun) Init() {
	c.Flags.StringVar(&c.configPath, "config", "rollers.textproto", "Path to the config file to validate.")
}

func (c *validateRun) Run(a subcommands.Application, args []string, env subcommands.Env) int {
	config, err := readConfig(c.configPath)
	if err != nil {
		fmt.Fprintf(a.GetErr(), "%s: %s\n", a.GetName(), err)
		return 1
	}
	// rollers.textproto files must be located in the repository root.
	repoRoot := filepath.Dir(c.configPath)
	if err := validate(context.Background(), repoRoot, config); err != nil {
		fmt.Fprintf(a.GetErr(), "%s: %s\n", a.GetName(), err)
		return 1
	}
	fmt.Fprintln(a.GetOut(), "Successful validation")
	return 0
}

func validate(ctx context.Context, repoRoot string, config *proto.Config) error {
	var hasJiriEntities bool
	cipdDependenciesMap := make(map[string]bool)
	for i, roller := range config.GetRollers() {
		toRollDesc := roller.ProtoReflect().Descriptor().Oneofs().ByName("to_roll")
		field := roller.ProtoReflect().WhichOneof(toRollDesc)
		if field == nil {
			return fmt.Errorf("entry %d is missing an entity to roll", i)
		}
		var toValidate interface {
			Validate(ctx context.Context, repoRoot string) error
		}
		switch field.Name() {
		case "submodule":
			toValidate = roller.GetSubmodule()
		case "cipd_packages":
			cipdPackages := roller.GetCipdPackages()
			if _, ok := cipdDependenciesMap[cipdPackages.DepName]; ok {
				return fmt.Errorf("dep_name %s is not unique", cipdPackages.DepName)
			}
			cipdDependenciesMap[cipdPackages.DepName] = true
			toValidate = cipdPackages
		case "jiri_project":
			toValidate = roller.GetJiriProject()
			hasJiriEntities = true
		case "jiri_packages":
			toValidate = roller.GetJiriPackages()
			hasJiriEntities = true
		default:
			log.Panicf("unknown to_roll type: %q", field.Name())
		}

		if err := toValidate.Validate(ctx, repoRoot); err != nil {
			return err
		}

		if schedule := roller.GetSchedule(); schedule != "" {
			if err := validateSchedule(schedule); err != nil {
				return err
			}
		}

		for _, email := range roller.GetNotifyEmails() {
			if err := validateEmail(email); err != nil {
				return err
			}
		}
	}
	if hasJiriEntities && config.GetDefaultCheckoutJiriManifest() == "" {
		return fmt.Errorf("default_checkout_jiri_manifest is required to enable jiri rollers")
	} else if !hasJiriEntities && config.GetDefaultCheckoutJiriManifest() != "" {
		return fmt.Errorf("default_checkout_jiri_manifest need not be set")
	}
	return nil
}

var withIntervalScheduleRE = regexp.MustCompile(`with (\d+\w+) interval`)

func validateSchedule(schedule string) error {
	if strings.HasPrefix(schedule, "with ") {
		sm := withIntervalScheduleRE.FindStringSubmatch(schedule)
		if sm == nil {
			return fmt.Errorf("invalid schedule %q", schedule)
		}
		_, err := time.ParseDuration(sm[1])
		if err != nil {
			return fmt.Errorf("invalid duration in schedule %q", schedule)
		}
	} else {
		_, err := cronexpr.Parse(schedule)
		if err != nil {
			return fmt.Errorf("invalid cron schedule %q", schedule)
		}
	}
	return nil
}

func validateEmail(email string) error {
	// Do a basic validity check to make sure it roughly looks like an email.
	if _, err := mail.ParseAddress(email); err != nil {
		return fmt.Errorf("invalid email %q", email)
	}
	return nil
}
