// Copyright The Monogon Project Authors.
// SPDX-License-Identifier: Apache-2.0

// 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.SplitN(line, " ", 2)
		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)
	}
}
