//go:build ignore
// +build ignore

package main

/*
	Generate asset_versions_gen.go.
*/

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

	"go.skia.org/infra/go/cipd"
	"go.skia.org/infra/go/depot_tools/deps_parser"
	"go.skia.org/infra/go/exec"
	"go.skia.org/infra/go/skerr"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/util"
)

const (
	TARGET_FILE = "asset_versions_gen.go"
	HEADER      = `// Code generated by "go run gen_versions.go"; DO NOT EDIT

package cipd

var PACKAGES = map[string]*Package{
`
	FOOTER = `}`
)

func genAssetVersionsGo(depsEntries deps_parser.DepsEntries, pkgDir, rootDir string) error {
	// Pull out only the CIPD dependencies.
	var pkgs []*cipd.Package
	for _, entry := range depsEntries {
		if entry.Type != deps_parser.DepType_Cipd {
			continue
		}
		pkg := &cipd.Package{
			Path:    entry.Path,
			Name:    entry.Id,
			Version: entry.Version,
		}
		if pkg.Path == "" {
			pkg.Path = "."
		}
		pkgs = append(pkgs, pkg)
	}

	// List the assets.
	assetsDir := path.Join(rootDir, "infra", "bots", "assets")
	entries, err := os.ReadDir(assetsDir)
	if err != nil {
		return skerr.Wrap(err)
	}
	for _, e := range entries {
		if e.IsDir() {
			contents, err := os.ReadFile(path.Join(assetsDir, e.Name(), "VERSION"))
			if err == nil {
				name := e.Name()
				fullName := fmt.Sprintf("skia/bots/%s", name)
				pkgs = append(pkgs, &cipd.Package{
					Path:    name,
					Name:    fullName,
					Version: cipd.VersionTag(strings.TrimSpace(string(contents))),
				})
			} else if !os.IsNotExist(err) {
				return skerr.Wrap(err)
			}
		}
	}

	// Write the file.
	sort.Sort(cipd.PackageSlice(pkgs))
	targetFile := path.Join(pkgDir, TARGET_FILE)
	if err := util.WithWriteFile(targetFile, func(w io.Writer) error {
		_, err := w.Write([]byte(HEADER))
		if err != nil {
			return err
		}
		for _, pkg := range pkgs {
			_, err := fmt.Fprintf(w, fmt.Sprintf(`	"%s": &Package{
		Path: "%s",
		Name: "%s",
		Version: "%s",
	},
`, pkg.Name, pkg.Path, pkg.Name, pkg.Version))
			if err != nil {
				return err
			}
		}
		_, err = w.Write([]byte(FOOTER))
		return err
	}); err != nil {
		return skerr.Wrap(err)
	}
	if _, err := exec.RunCwd(context.Background(), ".", "gofmt", "-s", "-w", targetFile); err != nil {
		return skerr.Wrap(err)
	}
	return nil
}

func genEnsureFile(entries deps_parser.DepsEntries, rootDir string) error {
	// We only use the ensure file on Linux.
	const platform = cipd.PlatformLinuxAmd64

	// Extract the dependency on CIPD itself.
	cipdEntry, ok := entries[cipd.PkgNameCIPD]
	if !ok {
		sklog.Fatal("Unable to find critical package %s", cipd.PkgNameCIPD)
	}
	delete(entries, cipdEntry.Id)

	// Sort package names for consistency.
	entryIDs := make([]string, 0, len(entries))
	for id := range entries {
		entryIDs = append(entryIDs, id)
	}
	sort.Strings(entryIDs)

	// Organize packages by destination path.
	byPath := map[string][]*deps_parser.DepsEntry{}
	longestIDLength := 0
	for _, entryID := range entryIDs {
		entry := entries[entryID]
		if entry.Type != deps_parser.DepType_Cipd {
			continue
		}
		pkgSplit := strings.Split(entry.Id, "/")
		pkgPlatform := pkgSplit[len(pkgSplit)-1]
		if util.In(pkgPlatform, cipd.Platforms) && pkgPlatform != platform {
			continue
		}
		byPath[entry.Path] = append(byPath[entry.Path], entry)
		if len(entry.Id) > longestIDLength {
			longestIDLength = len(entry.Id)
		}
	}

	// Sort path names for consistency.
	paths := make([]string, 0, len(byPath))
	for path := range byPath {
		paths = append(paths, path)
	}
	sort.Strings(paths)

	// Construct the ensure file.
	lines := strings.Split(fmt.Sprintf(`# This file is generated by go/cipd/gen_versions.go.
# DO NOT EDIT DIRECTLY.

# The CIPD server to use.
$ServiceURL %s

# This is the CIPD client itself.
%s %s
`, cipd.DefaultServiceURL, cipdEntry.Id, cipdEntry.Version), "\n")

	for _, path := range paths {
		entriesInPath := byPath[path]
		if path == "" {
			lines = append(lines, "@Subdir")
		} else {
			lines = append(lines, fmt.Sprintf("@Subdir %s", path))
		}
		for _, entry := range entriesInPath {
			spacer := strings.Repeat(" ", longestIDLength-len(entry.Id))
			lines = append(lines, fmt.Sprintf("%s %s%s", entry.Id, spacer, entry.Version))
		}
		lines = append(lines, "")
	}
	content := []byte(strings.Join(lines, "\n"))

	// Write the file.
	if err := os.WriteFile(filepath.Join(rootDir, "cipd.ensure"), content, os.ModePerm); err != nil {
		sklog.Fatal(err)
	}
	return nil
}

func main() {
	// Read and parse the DEPS file.
	_, filename, _, _ := runtime.Caller(0)
	pkgDir := path.Dir(filename)
	rootDir := path.Join(pkgDir, "..", "..")

	depsContents, err := os.ReadFile(filepath.Join(rootDir, "DEPS"))
	if err != nil {
		sklog.Fatal(err)
	}
	depsEntries, err := deps_parser.ParseDepsNoNormalize(string(depsContents))
	if err != nil {
		sklog.Fatal(err)
	}

	if err := genAssetVersionsGo(depsEntries, pkgDir, rootDir); err != nil {
		sklog.Fatal(err)
	}

	if err := genEnsureFile(depsEntries, rootDir); err != nil {
		sklog.Fatal(err)
	}
}
