// pushk pushes a new version of an app.
//
// See flag.Usage for details.
package main

import (
	"context"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"runtime"
	"sort"
	"strings"

	"go.skia.org/infra/go/skerr"

	"go.skia.org/infra/go/auth"
	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/exec"
	"go.skia.org/infra/go/gcr"
	"go.skia.org/infra/go/gerrit/rubberstamper"
	"go.skia.org/infra/go/git"
	"go.skia.org/infra/go/kube/clusterconfig"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/util"
)

const (
	// containerRegistryProject is the GCP project in which we store our Docker
	// images via Google Cloud Container Registry.
	containerRegistryProject = "skia-public"

	// Max number of revisions of an image to print when using --list.
	maxListSize = 10

	// All dirty images are tagged with this suffix.
	dirtyImageTagSuffix = "-dirty"
)

func init() {
	flag.Usage = func() {
		fmt.Printf("Usage: pushk <flags> [one or more image names]\n\n")
		fmt.Printf(`pushk pushes a new version of an app.

The command:
  1. Searches through the checked in kubernetes yaml files to determine which use the image(s).
  2. Modifies the kubernetes yaml files with the new version of the image(s).
  3. Applies the changes with kubectl.
  4. Commits the changes to the config repo via AutoSubmit, with approval by Rubber Stamper.

The config is stored in a separate repo that will automaticaly be checked out
under /tmp by default, or the value of the PUSHK_GITDIR environment variable if set.

The command applies the changes by default, or just changes the local yaml files
if --dry-run is supplied.

Examples:
  # Push an exact tag.
  pushk gcr.io/skia-public/fiddler:694900e3ca9468784a5794dc53382d1c8411ab07

  # Push the latest version of docserver.
  pushk docserver --message="Fix bug #1234"

  # Push the latest version of docserver to the skia-corp cluster.
  pushk docserver --only-cluster=skia-corp --message="Fix bug #1234"

  # Push the latest version of docserver and iap-proxy
  pushk docserver iap-proxy

  # Rollback docserver.
  pushk --rollback docserver

  # List the last few versions of the docserver image. Doesn't apply anything.
  pushk --list docserver

  # Compute any changes a push to docserver will make, but do not apply them.
  # Note that the YAML file(s) will be updated, but not committed or pushed.
  pushk --dry-run docserver

ENV:

  The config repo is checked out by default into '/tmp'. This can be
  changed by setting the environment variable PUSHK_GITDIR.
`)
		flag.PrintDefaults()
	}
}

// flags
var (
	onlyCluster             = flag.String("only-cluster", "", "If set then only push to the specified cluster.")
	configFile              = flag.String("config-file", "", "Absolute filename of the config.json file.")
	dryRun                  = flag.Bool("dry-run", false, "If true then do not run the kubectl command to apply the changes, and do not commit the changes to the config repo.")
	ignoreDirty             = flag.Bool("ignore-dirty", false, "If true, then do not fail out if the git repo is dirty.")
	list                    = flag.Bool("list", false, "List the last few versions of the given image.")
	message                 = flag.String("message", "Push", "Message to go along with the change.")
	rollback                = flag.Bool("rollback", false, "If true go back to the second most recent image, otherwise use most recent image.")
	runningInK8s            = flag.Bool("running-in-k8s", false, "If true, then does not use flags that do not work in the k8s environment. Eg: '--cluster' when doing 'kubectl apply'.")
	doNotOverrideDirtyImage = flag.Bool("do-not-override-dirty-image", false, "If true, then do not push if the latest checkedin image is dirty. Caveat: This only checks the k8s-config repository to determine if image is dirty, it does not check the live running k8s containers.")
	useTempCheckout         = flag.Bool("use-temp-checkout", false, "If true, checks out the config repo into a temporary directory and pushes from there.")
	verbose                 = flag.Bool("verbose", false, "Verbose runtime diagnostics.")
)

var (
	validTag = regexp.MustCompile(`^\d\d\d\d-\d\d-\d\dT\d\d_\d\d_\d\dZ-.+$`)
)

// filter strips the list of tags down to only the ones that conform to our
// constraints and also checks that there are enough tags. The results
// are sorted in ascending order, so oldest tags are first, newest tags
// are last.
func filter(tags []string) ([]string, error) {
	validTags := []string{}
	for _, t := range tags {
		if validTag.MatchString(t) {
			validTags = append(validTags, t)
		}
	}
	sort.Strings(validTags)
	if len(validTags) == 0 {
		return nil, skerr.Fmt("Not enough tags returned.\n Saw %s", tags)
	}
	return validTags, nil
}

// tagProvider is a type that returns the correct tag to push for the given imageName.
type tagProvider func(imageName string) ([]string, error)

// imageFromCmdLineImage handles image names, which can be either short, ala 'fiddler', or exact,
// such as gcr.io/skia-public/fiddler:694900e3ca9468784a5794dc53382d1c8411ab07, both of which can
// appear on the command-line.
func imageFromCmdLineImage(imageName string, tp tagProvider) (string, error) {
	if strings.HasPrefix(imageName, "gcr.io/") {
		if *rollback {
			return "", skerr.Fmt("Supplying a fully qualified image name and the --rollback flag are mutually exclusive.")
		}
		if *list {
			return "", skerr.Fmt("Supplying a fully qualified image name and the --list flag are mutually exclusive.")
		}
		return imageName, nil
	}
	// Get all the tags for the selected image.
	tags, err := tp(imageName)
	if err != nil {
		return "", skerr.Wrapf(err, "providing tags for image %s. Does this image exist?", imageName)
	}

	// Filter the tags
	tags, err = filter(tags)
	if err != nil {
		return "", skerr.Wrapf(err, "filtering tags for image %s", imageName)
	}

	if *list {
		if len(tags) > maxListSize {
			tags = tags[len(tags)-maxListSize:]
		}
		for _, tag := range tags {
			fmt.Println(tag)
		}
	}

	// Pick the target tag we want to move to.
	tag := tags[len(tags)-1]
	if *rollback {
		if len(tags) < 2 {
			return "", skerr.Fmt("No version of %s to rollback to.", imageName)
		}
		tag = tags[len(tags)-2]
	}

	// The full docker image name and tag of the image we want to deploy.
	return fmt.Sprintf("%s/%s/%s:%s", gcr.Server, containerRegistryProject, imageName, tag), nil
}

// byClusterFromChanged returns a map from cluster name to the list of modified
// files in that cluster.
func byClusterFromChanged(gitDir string, changed util.StringSet) (map[string][]string, error) {
	// Find all the directory names, which are really cluster names.
	// filenames will be absolute directory names, e.g.
	// /tmp/k8s-config/skia-public/task-scheduler-be-staging.yaml
	byCluster := map[string][]string{}

	// The first part of that is
	for _, filename := range changed.Keys() {
		// /tmp/k8s-config/skia-public/task-scheduler-be-staging.yaml => skia-public/task-scheduler-be-staging.yaml
		rel, err := filepath.Rel(gitDir, filename)
		if err != nil {
			return nil, err
		}
		// skia-public/task-scheduler-be-staging.yaml => skia-public
		cluster := filepath.Dir(rel)
		arr, ok := byCluster[cluster]
		if !ok {
			arr = []string{filename}
		} else {
			arr = append(arr, filename)
		}
		byCluster[cluster] = arr
	}
	return byCluster, nil
}

func main() {
	common.Init()

	ctx := context.Background()
	cfg, checkout, err := clusterconfig.NewWithCheckout(ctx, *configFile)
	if err != nil {
		sklog.Fatal(err)
	}
	if *useTempCheckout {
		tmp, err := git.NewTempCheckout(ctx, cfg.Repo)
		if err != nil {
			sklog.Fatal(err)
		}
		defer tmp.Delete()
		checkout = tmp.Checkout
	}

	output, err := checkout.Git(ctx, "status", "-s")
	if err != nil {
		sklog.Fatal(err)
	}
	if strings.TrimSpace(output) != "" {
		if !*ignoreDirty {
			sklog.Fatalf("Found dirty checkout in %s:\n%s", checkout.Dir(), output)
		}
	} else {
		if err := checkout.UpdateBranch(ctx, git.MainBranch); err != nil {
			sklog.Fatal(err)
		}
	}

	dirMatch := "*"
	if *onlyCluster != "" {
		dirMatch = *onlyCluster
	}
	glob := fmt.Sprintf("/%s/*.yaml", dirMatch)
	// Get all the yaml files.
	filenames, err := filepath.Glob(filepath.Join(checkout.Dir(), glob))
	if err != nil {
		sklog.Fatal(err)
	}

	tokenSource := auth.NewGCloudTokenSource(containerRegistryProject)
	imageNames := flag.Args()
	if len(imageNames) == 0 {
		fmt.Println("At least one image name needs to be supplied.")
		flag.Usage()
		os.Exit(1)
	}
	sklog.Infof("Pushing the following images: %q", imageNames)

	gcrTagProvider := func(imageName string) ([]string, error) {
		tagsResp, err := gcr.NewClient(tokenSource, containerRegistryProject, imageName).Tags(ctx)
		if err != nil {
			return nil, err
		}
		return tagsResp.Tags, nil
	}

	// Search through the yaml files looking for those that use the provided image names.
	changed := util.StringSet{}
	for _, imageName := range imageNames {
		image, err := imageFromCmdLineImage(imageName, gcrTagProvider)
		if err != nil {
			sklog.Fatal(err)
		}
		if *list {
			// imageFromCmdLineImage printed out the tags, so nothing more to do.
			continue
		}

		// imageRegex has the following groups returned on match:
		// 0 - the entire line
		// 1 - the prefix, i.e. image:, with correct spacing.
		// 2 - full image name
		// 3 - just the tag
		//
		// We pull out the 'prefix' so we can use it when
		// we rewrite the image: line so the indent level is
		// unchanged.
		parts := strings.SplitN(image, ":", 2)
		if len(parts) != 2 {
			sklog.Fatalf("Failed to split imageName: %v", parts)
		}
		imageNoTag := parts[0]
		imageRegex := regexp.MustCompile(fmt.Sprintf(`^(\s+image:\s+)(%s):(.*)$`, imageNoTag))

		// Loop over all the yaml files and update tags for the given imageName.
		for _, filename := range filenames {
			b, err := ioutil.ReadFile(filename)
			if err != nil {
				sklog.Errorf("Failed to read %q (skipping): %s", filename, err)
				continue
			}
			lines := strings.Split(string(b), "\n")
			for i, line := range lines {
				matches := imageRegex.FindStringSubmatch(line)
				if len(matches) != 4 {
					continue
				}
				if *doNotOverrideDirtyImage && strings.HasSuffix(matches[3], dirtyImageTagSuffix) {
					sklog.Infof("%s is dirty. Not pushing to it since --do-not-override-dirty-image is set.", matches[3])
					continue
				}

				if *verbose {
					fmt.Printf("Changed file: %s to image: %s\n", filename, image)
				}

				changed[filename] = true
				lines[i] = matches[1] + image
			}
			if changed[filename] {
				err := util.WithWriteFile(filename, func(w io.Writer) error {
					_, err := w.Write([]byte(strings.Join(lines, "\n")))
					return err
				})
				if err != nil {
					sklog.Fatalf("Failed to write update config file %q: %s", filename, err)
				}
			}
		}
	}

	// Were any files updated?
	if len(changed) != 0 {
		byCluster, err := byClusterFromChanged(checkout.Dir(), changed)
		if err != nil {
			sklog.Fatal(err)
		}

		// Find the location of the attach.sh shell script.
		_, filename, _, _ := runtime.Caller(0)
		attachFilename := filepath.Join(filepath.Dir(filename), "../../attach.sh")

		// Then loop over cluster names and apply all changed files for that
		// cluster.
		for cluster, files := range byCluster {
			if *verbose {
				fmt.Printf("Starting to apply changes to cluster: %s\n", cluster)
			}

			filenameFlag := fmt.Sprintf("--filename=%s\n", strings.Join(files, ","))

			// By default run everything through infra/kube/attach.sh.
			name := attachFilename
			kubectlArgs := []string{cluster, "kubectl", "apply", filenameFlag}
			// But not if we are running in k8s.
			if *runningInK8s {
				name = "kubectl"
				kubectlArgs = []string{"apply", filenameFlag}
			}
			fmt.Printf("\n%s %s\n", name, strings.Join(kubectlArgs, " "))

			if !*dryRun {
				for filename := range changed {
					// /tmp/k8s-config/skia-public/task-scheduler-be-staging.yaml => skia-public/task-scheduler-be-staging.yaml
					rel, err := filepath.Rel(checkout.Dir(), filename)
					if err != nil {
						sklog.Fatal(err)
					}
					msg, err := checkout.Git(ctx, "add", rel)
					if err != nil {
						sklog.Fatalf("Failed to stage changes to the config repo: %s: %q", err, msg)
					}
				}

				if err := exec.Run(context.Background(), &exec.Command{
					Name:      name,
					Args:      kubectlArgs,
					LogStderr: true,
					LogStdout: true,
				}); err != nil {
					sklog.Errorf("Failed to run: %s", err)
				}
			}
		}

		// Once everything is pushed, then commit and push the changes.
		msg, err := checkout.Git(ctx, "diff", "--cached", "--name-only")
		if err != nil {
			sklog.Fatalf("Failed to diff :%s: %q", err, msg)
		}
		if msg == "" {
			sklog.Infof("Not pushing since no files changed.")
			return
		}

		if *message == "" {
			*message = "Push"
		}

		messageWithBody := *message + "\n\n" + rubberstamper.RandomChangeID()
		msg, err = checkout.Git(ctx, "commit", "-m", messageWithBody)
		if err != nil {
			sklog.Fatalf("Failed to commit to the config repo: %s: %q", err, msg)
		}

		msg, err = checkout.Git(ctx, "push", git.DefaultRemote, rubberstamper.PushRequestAutoSubmit)
		if err != nil {
			sklog.Fatalf("Failed to push the config repo: %s: %q", err, msg)
		}
	} else {
		fmt.Println("Nothing to do.")
	}
}
