// 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)
	if err != nil {
		log.Fatalf("failed to marshal version: %v", err)
	}
	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)
	}
}
