// 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]+)$`)
	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)
	}

	version := &spec.Version{}

	commitHash := values["STABLE_MONOGON_gitCommit"]
	if commitHash != "" {
		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.GitInformation = &spec.Version_GitInformation{
			CommitHash:     commitHash[:8],
			BuildTreeState: buildTreeState,
		}
	}

	productVersion := values["STABLE_MONOGON_"+flagProduct+"_version"]
	if productVersion != "" {
		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() {
			preCommitOffset := rePrereleaseCommitOffset.FindStringSubmatch(el)
			preGitHash := rePrereleaseGitHash.FindStringSubmatch(el)
			switch {
			case el == "":
				// Skip empty slices which happens when there's a semver string with no
				// prerelease data.
			case el == "nostamp":
				// Ignore field, we have it from the global monorepo state.
			case preCommitOffset != nil:
				offset, err := strconv.ParseUint(preCommitOffset[1], 10, 64)
				if err != nil {
					log.Fatalf("Invalid commit offset value: %v", err)
				}
				if version.GitInformation == nil {
					log.Fatalf("Have git offset but no git commit")
				}
				version.GitInformation.CommitsSinceRelease = offset
			case el == "dirty":
				// 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)
	}
}
