// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

// protobuf-compile is a helper tool for running protoc against all of the
// .proto files in this repository using specific versions of protoc and
// protoc-gen-go, to ensure consistent results across all development
// environments.
//
// protoc itself isn't a Go tool, so we need to use a custom strategy to
// install and run it. The official releases are built only for a subset of
// platforms that Go can potentially target, so this tool will fail if you
// are using a platform other than the ones this wrapper tool has explicit
// support for. In that case you'll need to either run this tool on a supported
// platform or to recreate what it does manually using a protoc you've built
// and installed yourself.
package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"

	"github.com/hashicorp/go-getter"
)

const protocVersion = "3.15.6"

// We also use protoc-gen-go and its grpc addon, but since these are Go tools
// in Go modules our version selection for these comes from our top-level
// go.mod, as with all other Go dependencies. If you want to switch to a newer
// version of either tool then you can upgrade their modules in the usual way.
const protocGenGoPackage = "github.com/golang/protobuf/protoc-gen-go"
const protocGenGoGrpcPackage = "google.golang.org/grpc/cmd/protoc-gen-go-grpc"

type protocStep struct {
	DisplayName string
	WorkDir     string
	Args        []string
}

var protocSteps = []protocStep{
	{
		"tfplugin5 (provider wire protocol version 5)",
		"internal/tfplugin5",
		[]string{"--go_out=paths=source_relative,plugins=grpc:.", "./tfplugin5.proto"},
	},
	{
		"tfplugin6 (provider wire protocol version 6)",
		"internal/tfplugin6",
		[]string{"--go_out=paths=source_relative,plugins=grpc:.", "./tfplugin6.proto"},
	},
	{
		"tfplan (plan file serialization)",
		"internal/plans/internal/planproto",
		[]string{"--go_out=paths=source_relative:.", "planfile.proto"},
	},
}

func main() {
	if len(os.Args) != 2 {
		log.Fatal("Usage: go run github.com/hashicorp/terraform/tools/protobuf-compile <basedir>")
	}
	baseDir := os.Args[1]
	workDir := filepath.Join(baseDir, "tools/protobuf-compile/.workdir")

	protocLocalDir := filepath.Join(workDir, "protoc-v"+protocVersion)
	if _, err := os.Stat(protocLocalDir); os.IsNotExist(err) {
		err := downloadProtoc(protocVersion, protocLocalDir)
		if err != nil {
			log.Fatal(err)
		}
	} else {
		log.Printf("already have protoc v%s in %s", protocVersion, protocLocalDir)
	}

	protocExec := filepath.Join(protocLocalDir, "bin/protoc")

	protocGenGoExec, err := buildProtocGenGo(workDir)
	if err != nil {
		log.Fatal(err)
	}
	_, err = buildProtocGenGoGrpc(workDir)
	if err != nil {
		log.Fatal(err)
	}

	protocExec, err = filepath.Abs(protocExec)
	if err != nil {
		log.Fatal(err)
	}
	protocGenGoExec, err = filepath.Abs(protocGenGoExec)
	if err != nil {
		log.Fatal(err)
	}
	protocGenGoGrpcExec, err := filepath.Abs(protocGenGoExec)
	if err != nil {
		log.Fatal(err)
	}

	// For all of our steps we'll run our localized protoc with our localized
	// protoc-gen-go.
	baseCmdLine := []string{protocExec, "--plugin=" + protocGenGoExec, "--plugin=" + protocGenGoGrpcExec}

	for _, step := range protocSteps {
		log.Printf("working on %s", step.DisplayName)

		cmdLine := make([]string, 0, len(baseCmdLine)+len(step.Args))
		cmdLine = append(cmdLine, baseCmdLine...)
		cmdLine = append(cmdLine, step.Args...)

		cmd := &exec.Cmd{
			Path:   cmdLine[0],
			Args:   cmdLine[1:],
			Dir:    step.WorkDir,
			Env:    os.Environ(),
			Stdout: os.Stdout,
			Stderr: os.Stderr,
		}
		err := cmd.Run()
		if err != nil {
			log.Printf("failed to compile: %s", err)
		}
	}

}

// downloadProtoc downloads the given version of protoc into the given
// directory.
func downloadProtoc(version string, localDir string) error {
	protocURL, err := protocDownloadURL(version)
	if err != nil {
		return err
	}

	log.Printf("downloading and extracting protoc v%s from %s into %s", version, protocURL, localDir)

	// For convenience, we'll be using go-getter to actually download this
	// thing, so we need to turn the real URL into the funny sort of pseudo-URL
	// thing that go-getter wants.
	goGetterURL := protocURL + "?archive=zip"

	err = getter.Get(localDir, goGetterURL)
	if err != nil {
		return fmt.Errorf("failed to download or extract the package: %s", err)
	}

	return nil
}

// buildProtocGenGo uses the Go toolchain to fetch the module containing
// protoc-gen-go and then build an executable into the working directory.
//
// If successful, it returns the location of the executable.
func buildProtocGenGo(workDir string) (string, error) {
	exeSuffixRaw, err := exec.Command("go", "env", "GOEXE").Output()
	if err != nil {
		return "", fmt.Errorf("failed to determine executable suffix: %s", err)
	}
	exeSuffix := strings.TrimSpace(string(exeSuffixRaw))
	exePath := filepath.Join(workDir, "protoc-gen-go"+exeSuffix)
	log.Printf("building %s as %s", protocGenGoPackage, exePath)

	cmd := exec.Command("go", "build", "-o", exePath, protocGenGoPackage)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err = cmd.Run()
	if err != nil {
		return "", fmt.Errorf("failed to build %s: %s", protocGenGoPackage, err)
	}

	return exePath, nil
}

// buildProtocGenGoGrpc uses the Go toolchain to fetch the module containing
// protoc-gen-go-grpc and then build an executable into the working directory.
//
// If successful, it returns the location of the executable.
func buildProtocGenGoGrpc(workDir string) (string, error) {
	exeSuffixRaw, err := exec.Command("go", "env", "GOEXE").Output()
	if err != nil {
		return "", fmt.Errorf("failed to determine executable suffix: %s", err)
	}
	exeSuffix := strings.TrimSpace(string(exeSuffixRaw))
	exePath := filepath.Join(workDir, "protoc-gen-go-grpc"+exeSuffix)
	log.Printf("building %s as %s", protocGenGoGrpcPackage, exePath)

	cmd := exec.Command("go", "build", "-o", exePath, protocGenGoGrpcPackage)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err = cmd.Run()
	if err != nil {
		return "", fmt.Errorf("failed to build %s: %s", protocGenGoGrpcPackage, err)
	}

	return exePath, nil
}

// protocDownloadURL returns the URL to try to download the protoc package
// for the current platform or an error if there's no known URL for the
// current platform.
func protocDownloadURL(version string) (string, error) {
	platformKW := protocPlatform()
	if platformKW == "" {
		return "", fmt.Errorf("don't know where to find protoc for %s on %s", runtime.GOOS, runtime.GOARCH)
	}
	return fmt.Sprintf("https://github.com/protocolbuffers/protobuf/releases/download/v%s/protoc-%s-%s.zip", protocVersion, protocVersion, platformKW), nil
}

// protocPlatform returns the package name substring for the current platform
// in the naming convention used by official protoc packages, or an empty
// string if we don't know how protoc packaging would describe current
// platform.
func protocPlatform() string {
	goPlatform := runtime.GOOS + "_" + runtime.GOARCH

	switch goPlatform {
	case "linux_amd64":
		return "linux-x86_64"
	case "linux_arm64":
		return "linux-aarch_64"
	case "darwin_amd64":
		return "osx-x86_64"
	case "darwin_arm64":
		// As of 3.15.6 there isn't yet an osx-aarch_64 package available,
		// so we'll install the x86_64 version and hope Rosetta can handle it.
		return "osx-x86_64"
	case "windows_amd64":
		return "win64" // for some reason the windows packages don't have a CPU architecture part
	default:
		return ""
	}
}
