// Copyright 2020 The Monogon Project Authors.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// gotoolwrap is a tiny wrapper used to run executables that expect a standard
// Go development environment setup to act on the monogon workspace. Notably,
// it's used in Bazel rules to run tools like gofmt when invoked by some kinds
// of code generation tools.
//
// Usage: ./gotoolwrap executable arg1 arg2
//
// gotoolwrap expects the following environment variables to be set (and unsets
// them before calling the given executable):
//  - GOTOOLWRAP_GOPATH: A synthetic GOPATH, eg. one generated by rules_go's
//  				     go_path target.
//  - GOTOOLWRAP_GOROOT: A Go SDK's GOROOT, eg. one from rules_go's GoSDK
//                       provider.
//
// gotoolwrap will set PATH to contain GOROOT/bin, and set GOPATH and GOROOT as
// resolved, absolute paths. Absolute paths are expected by tools like 'gofmt'.

package main

import (
	"errors"
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

func main() {
	gopath := os.Getenv("GOTOOLWRAP_GOPATH")
	if gopath == "" {
		log.Fatal("GOTOOLWRAP_GOPATH must be set")
	}

	goroot := os.Getenv("GOTOOLWRAP_GOROOT")
	if goroot == "" {
		log.Fatal("GOTOOLWRAP_GOROOT must be set")
	}

	if len(os.Args) < 2 {
		log.Fatalf("No command specified")
	}

	// Resolve gopath and goroot to absolute paths.
	gopathAbs, err := filepath.Abs(gopath)
	if err != nil {
		log.Fatalf("Abs(%q): %v", gopath, err)
	}
	gorootAbs, err := filepath.Abs(goroot)
	if err != nil {
		log.Fatalf("Abs(%q): %v", goroot, err)
	}

	// Ensure the resolved GOROOT has a bin/go and bin/gofmt.
	gorootBin := filepath.Join(gorootAbs, "bin")
	stat, err := os.Stat(gorootBin)
	if err != nil {
		log.Fatalf("Could not stat $GOTOOLWRAP_GOROOT/bin (%q): %v", gorootBin, err)
	}
	if !stat.IsDir() {
		log.Fatalf("$GOTOOLWRAP_GOROOT/bin (%q) is not a directory", gorootBin)
	}
	// We list all files inside so that we can print them to the user for
	// debugging purposes if that's not the case.
	binFiles := make(map[string]bool)
	files, err := os.ReadDir(gorootBin)
	if err != nil {
		log.Fatalf("Could not read dir $GOTOOLWRAP_GOROOT/bin (%q): %v", gorootBin, err)
	}
	for _, f := range files {
		if f.IsDir() {
			continue
		}
		binFiles[f.Name()] = true
	}
	if !binFiles["go"] || !binFiles["gofmt"] {
		msg := "no files"
		if len(binFiles) > 0 {
			var names []string
			for name, _ := range binFiles {
				names = append(names, fmt.Sprintf("%q", name))
			}
			msg = fmt.Sprintf(": %s", strings.Join(names, ", "))
		}
		log.Fatalf("$GOTOOLWRAP_GOROOT/bin (%q) does not contain go and/or gofmt, found %s", gorootBin, msg)
	}

	// Make new PATH.
	path := os.Getenv("PATH")
	if path == "" {
		path = gorootBin
	} else {
		path = fmt.Sprintf("%s:%s", gorootBin, path)
	}

	cmd := exec.Command(os.Args[1], os.Args[2:]...)

	// Copy current env into command's env, filtering out GOTOOLWRAP env vars
	// and PATH (which we set ourselves).
	for _, v := range os.Environ() {
		if strings.HasPrefix(v, "GOTOOLWRAP_GOROOT=") {
			continue
		}
		if strings.HasPrefix(v, "GOTOOLWRAP_GOPATH=") {
			continue
		}
		if strings.HasPrefix(v, "PATH=") {
			continue
		}
		cmd.Env = append(cmd.Env, v)
	}
	// Create a temporary cache directory and remove everything afterwards.
	// Based on code from
	// @io_bazel_rules_go//go/tools/builders:stdliblist.go L174
	tempDir, err := os.MkdirTemp("", "gocache")
	if err != nil {
		log.Fatalf("Cannot create temporary directory: %v", err)
	}
	defer os.RemoveAll(tempDir)

	cmd.Env = append(cmd.Env,
		fmt.Sprintf("GOROOT=%s", gorootAbs),
		fmt.Sprintf("GOPATH=%s", gopathAbs),
		fmt.Sprintf("PATH=%s", path),
		fmt.Sprintf("GO111MODULE=off"),
		fmt.Sprintf("GOCACHE=%s", tempDir),
	)

	// Run the command interactively.
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Stdin = os.Stdin
	if err := cmd.Run(); err != nil {
		var exitErr *exec.ExitError
		if errors.As(err, &exitErr) {
			os.Exit(exitErr.ExitCode())
		} else {
			log.Fatalf("Could not run %q: %v", os.Args[1], err)
		}
	}
}
