// Package main implements 'stampgo', a tool to convert build status data into a
// version.spec.Version proto, which is then embedded into a Go source file.
package main

import (
	"bufio"
	"flag"
	"fmt"
	"log"
	"os"
	"regexp"
	"strconv"
	"strings"

	"github.com/coreos/go-semver/semver"
	"google.golang.org/protobuf/proto"

	"source.monogon.dev/version/spec"
)

var (
	flagStatusFile string
	flagOutFile    string
	flagImportpath string
	flagProduct    string
)

var (
	rePrereleaseCommitOffset = regexp.MustCompile(`^dev([0-9]+)$`)
	rePrereleaseDirty        = regexp.MustCompile(`^dirty$`)
	rePrereleaseGitHash      = regexp.MustCompile(`^g[0-9a-f]+$`)
)

func init() {
	flag.StringVar(&flagStatusFile, "status_file", "", "path to bazel workspace status file")
	flag.StringVar(&flagOutFile, "out_file", "version.go", "path to os-release output file")
	flag.StringVar(&flagImportpath, "importpath", "", "importpath of generated source")
	flag.StringVar(&flagProduct, "product", "", "product name within the monogon source tree")
}

// parseStatusFile reads and parses a Bazel build status file and returns
// a string -> string map based on its contents.
func parseStatusFile(path string) (map[string]string, error) {
	f, err := os.Open(path)
	if err != nil {
		return nil, fmt.Errorf("open failed: %w", err)
	}
	defer f.Close()

	res := make(map[string]string)
	scanner := bufio.NewScanner(f)
	for scanner.Scan() {
		line := scanner.Text()
		parts := strings.Split(line, " ")
		if len(parts) != 2 {
			return nil, fmt.Errorf("invalid line: %q", line)
		}
		k, v := parts[0], parts[1]
		if k == "" {
			return nil, fmt.Errorf("invalid line: %q", line)
		}
		if _, ok := res[k]; ok {
			return nil, fmt.Errorf("repeated key %q", k)
		}
		res[k] = v
	}
	return res, nil
}

func main() {
	flag.Parse()
	if flagImportpath == "" {
		log.Fatalf("Importpath must be set")
	}
	importpathParts := strings.Split(flagImportpath, "/")
	packageName := importpathParts[len(importpathParts)-1]

	values, err := parseStatusFile(flagStatusFile)
	if err != nil {
		log.Fatalf("Failed to read workspace status file: %v", err)
	}

	commitHash := values["STABLE_MONOGON_gitCommit"]
	if commitHash == "" {
		log.Fatalf("No git commit in workspace status")
	}
	if len(commitHash) < 8 {
		log.Fatalf("Git commit hash too short")
	}
	buildTreeState := spec.Version_GitInformation_BUILD_TREE_STATE_INVALID
	switch values["STABLE_MONOGON_gitTreeState"] {
	case "clean":
		buildTreeState = spec.Version_GitInformation_BUILD_TREE_STATE_CLEAN
	case "dirty":
		buildTreeState = spec.Version_GitInformation_BUILD_TREE_STATE_DIRTY
	default:
		log.Fatalf("Invalid git tree state %q", values["STABLE_MONOGON_gitTreeState"])
	}

	version := &spec.Version{
		GitInformation: &spec.Version_GitInformation{
			CommitHash:     commitHash[:8],
			BuildTreeState: buildTreeState,
		},
	}

	productVersion := values["STABLE_MONOGON_"+flagProduct+"_version"]
	if productVersion != "" {
		if productVersion[0] != 'v' {
			log.Fatalf("Invalid %s version %q: does not start with v", flagProduct, productVersion)
		}
		productVersion = productVersion[1:]
		v, err := semver.NewVersion(productVersion)
		if err != nil {
			log.Fatalf("Invalid %s version %q: %v", flagProduct, productVersion, err)
		}
		// Parse prerelease strings (v1.2.3-foo-bar -> [foo, bar])
		for _, el := range v.PreRelease.Slice() {
			// Skip empty slices which happens when there's a semver string with no
			// prerelease data.
			if el == "" {
				continue
			}
			preCommitOffset := rePrereleaseCommitOffset.FindStringSubmatch(el)
			preDirty := rePrereleaseDirty.FindStringSubmatch(el)
			preGitHash := rePrereleaseGitHash.FindStringSubmatch(el)
			switch {
			case preCommitOffset != nil:
				offset, err := strconv.ParseUint(preCommitOffset[1], 10, 64)
				if err != nil {
					log.Fatalf("Invalid commit offset value: %v", err)
				}
				version.GitInformation.CommitsSinceRelease = offset
			case preDirty != nil:
				// Ignore field, we have it from the global monorepo state.
			case preGitHash != nil:
				// Ignore field, we have it from the global monorepo state.
			default:
				log.Fatalf("Invalid prerelease string %q (in %q)", el, productVersion)
			}
		}
		version.Release = &spec.Version_Release{
			Major: v.Major,
			Minor: v.Minor,
			Patch: v.Patch,
		}
	}

	versionBytes, err := proto.Marshal(version)
	literalBytes := make([]string, len(versionBytes))
	for i, by := range versionBytes {
		literalBytes[i] = fmt.Sprintf("0x%02x", by)
	}

	content := []string{
		`// Generated by //version/stampgo`,
		`package ` + packageName,
		``,
		`import (`,
		`	"fmt"`,
		`	"os"`,
		``,
		`	"google.golang.org/protobuf/proto"`,
		``,
		`	"source.monogon.dev/version/spec"`,
		`)`,
		``,
		`var raw = []byte{`,
		`	` + strings.Join(literalBytes, ", ") + `,`,
		`}`,
		``,
		`var Version *spec.Version`,
		``,
		`func init() {`,
		`	var version spec.Version`,
		`	if err := proto.Unmarshal(raw, &version); err != nil {`,
		`		fmt.Fprintf(os.Stderr, "Invalid stamped version: %v\n", err)`,
		`	}`,
		`	Version = &version`,
		`}`,
		``,
	}

	if err := os.WriteFile(flagOutFile, []byte(strings.Join(content, "\n")), 0644); err != nil {
		log.Fatalf("Failed to write output file: %v", err)
	}
}
