// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"flag"
	"fmt"
	"go/go2go"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
)

var gotool = filepath.Join(runtime.GOROOT(), "bin", "go")

var cmds = map[string]bool{
	"build":     true,
	"run":       true,
	"test":      true,
	"translate": true,
}

func main() {
	flag.Usage = usage
	flag.Parse()

	args := flag.Args()
	if len(args) < 1 {
		usage()
	}

	if !cmds[args[0]] {
		usage()
	}

	importerTmpdir, err := ioutil.TempDir("", "go2go")
	if err != nil {
		log.Fatal(err)
	}
	defer os.RemoveAll(importerTmpdir)

	importer := go2go.NewImporter(importerTmpdir)

	var rundir string
	if args[0] == "run" {
		tmpdir := copyToTmpdir(args[1:])
		defer os.RemoveAll(tmpdir)
		translate(importer, tmpdir)
		nargs := []string{"run"}
		for _, arg := range args[1:] {
			base := filepath.Base(arg)
			f := strings.TrimSuffix(base, ".go2") + ".go"
			nargs = append(nargs, f)
		}
		args = nargs
		rundir = tmpdir
	} else if args[0] == "translate" && isGo2Files(args[1:]...) {
		for _, arg := range args[1:] {
			translateFile(importer, arg)
		}
	} else {
		for _, dir := range expandPackages(args[1:]) {
			translate(importer, dir)
		}
	}

	if args[0] != "translate" {
		cmd := exec.Command(gotool, args...)
		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		cmd.Dir = rundir
		gopath := importerTmpdir
		if go2path := os.Getenv("GO2PATH"); go2path != "" {
			gopath += string(os.PathListSeparator) + go2path
		}
		if oldGopath := os.Getenv("GOPATH"); oldGopath != "" {
			gopath += string(os.PathListSeparator) + oldGopath
		}
		cmd.Env = append(os.Environ(),
			"GOPATH="+gopath,
			"GO111MODULE=off",
		)
		if err := cmd.Run(); err != nil {
			die(fmt.Sprintf("%s %v failed: %v", gotool, args, err))
		}
	}
}

// isGo2Files reports whether the arguments are a list of .go2 files.
func isGo2Files(args ...string) bool {
	for _, arg := range args {
		if filepath.Ext(arg) != ".go2" {
			return false
		}
	}
	return true
}

// expandPackages returns a list of directories expanded from packages.
func expandPackages(pkgs []string) []string {
	if len(pkgs) == 0 {
		return []string{"."}
	}
	go2path := os.Getenv("GO2PATH")
	var dirs []string
pkgloop:
	for _, pkg := range pkgs {
		if go2path != "" {
			for _, pd := range strings.Split(go2path, string(os.PathListSeparator)) {
				d := filepath.Join(pd, "src", pkg)
				if fi, err := os.Stat(d); err == nil && fi.IsDir() {
					dirs = append(dirs, d)
					continue pkgloop
				}
			}
		}

		cmd := exec.Command(gotool, "list", "-f", "{{.Dir}}", pkg)
		cmd.Stderr = os.Stderr
		if go2path != "" {
			gopath := go2path
			if oldGopath := os.Getenv("GOPATH"); oldGopath != "" {
				gopath += string(os.PathListSeparator) + oldGopath
			}
			cmd.Env = append(os.Environ(),
				"GOPATH="+gopath,
				"GO111MODULE=off",
			)
		}
		out, err := cmd.Output()
		if err != nil {
			die(fmt.Sprintf("%s list %q failed: %v", gotool, pkg, err))
		}
		dirs = append(dirs, strings.Split(string(out), "\n")...)
	}
	return dirs
}

// copyToTmpdir copies files into a temporary directory.
func copyToTmpdir(files []string) string {
	if len(files) == 0 {
		die("no files to run")
	}
	tmpdir, err := ioutil.TempDir("", "go2go-run")
	if err != nil {
		die(err.Error())
	}
	for _, file := range files {
		data, err := ioutil.ReadFile(file)
		if err != nil {
			die(err.Error())
		}
		if err := ioutil.WriteFile(filepath.Join(tmpdir, filepath.Base(file)), data, 0444); err != nil {
			die(err.Error())
		}
	}
	return tmpdir
}

// usage reports a usage message and exits with failure.
func usage() {
	fmt.Fprint(os.Stderr, `Usage: go2go <command> [arguments]

The commands are:

	build      translate and build packages
	run        translate and run list of files
	test       translate and test packages
	translate  translate .go2 files into .go files
`)
	os.Exit(2)
}

// die reports an error and exits.
func die(msg string) {
	fmt.Fprintln(os.Stderr, msg)
	os.Exit(1)
}
