//===-- llvm-go.go - go tool wrapper for LLVM -----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This tool lets us build LLVM components within the tree by setting up a
// $GOPATH that resembles a tree fetched in the normal way with "go get".
//
//===----------------------------------------------------------------------===//

package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
)

const (
	linkmodeComponentLibs = "component-libs"
	linkmodeDylib         = "dylib"
)

type pkg struct {
	llvmpath, pkgpath string
}

var packages = []pkg{
	{"bindings/go/llvm", "llvm.org/llvm/bindings/go/llvm"},
}

type compilerFlags struct {
	cpp, cxx, ld string
}

var components = []string{
	"all-targets",
	"analysis",
	"asmparser",
	"asmprinter",
	"bitreader",
	"bitwriter",
	"codegen",
	"core",
	"coroutines",
	"debuginfodwarf",
	"executionengine",
	"instrumentation",
	"interpreter",
	"ipo",
	"irreader",
	"linker",
	"mc",
	"mcjit",
	"objcarcopts",
	"option",
	"profiledata",
	"scalaropts",
	"support",
	"target",
}

func llvmConfig(args ...string) string {
	configpath := os.Getenv("LLVM_CONFIG")
	if configpath == "" {
		bin, _ := filepath.Split(os.Args[0])
		configpath = filepath.Join(bin, "llvm-config")
	}

	cmd := exec.Command(configpath, args...)
	cmd.Stderr = os.Stderr
	out, err := cmd.Output()
	if err != nil {
		panic(err.Error())
	}

	outstr := string(out)
	outstr = strings.TrimSuffix(outstr, "\n")
	outstr = strings.Replace(outstr, "\n", " ", -1)
	return outstr
}

func llvmFlags() compilerFlags {
	args := append([]string{"--ldflags", "--libs", "--system-libs"}, components...)
	ldflags := llvmConfig(args...)
	stdLibOption := ""
	if strings.Contains(llvmConfig("--cxxflags"), "-stdlib=libc++") {
		// If libc++ is used to build LLVM libraries, -stdlib=libc++ is
		// needed to resolve dependent symbols
		stdLibOption = "-stdlib=libc++"
	}
	if runtime.GOOS == "aix" {
		// AIX linker does not honour `-rpath`, the closest substitution
		// is `-blibpath`
		ldflags = "-Wl,-blibpath:" + llvmConfig("--libdir") + " " + ldflags
	} else if runtime.GOOS != "darwin" {
		// OS X doesn't like -rpath with cgo. See:
		// https://github.com/golang/go/issues/7293
		ldflags = "-Wl,-rpath," + llvmConfig("--libdir") + " " + ldflags
	}
	return compilerFlags{
		cpp: llvmConfig("--cppflags"),
		cxx: "-std=c++14" + " " + stdLibOption,
		ld:  ldflags,
	}
}

func addTag(args []string, tag string) []string {
	args = append([]string{}, args...)
	addedTag := false
	for i, a := range args {
		if strings.HasPrefix(a, "-tags=") {
			args[i] = a + " " + tag
			addedTag = true
		} else if a == "-tags" && i+1 < len(args) {
			args[i+1] = args[i+1] + " " + tag
			addedTag = true
		}
	}
	if !addedTag {
		args = append([]string{args[0], "-tags", tag}, args[1:]...)
	}
	return args
}

func printComponents() {
	fmt.Println(strings.Join(components, " "))
}

func printConfig() {
	flags := llvmFlags()

	fmt.Printf(`// +build !byollvm

// This file is generated by llvm-go, do not edit.

package llvm

/*
#cgo CPPFLAGS: %s
#cgo CXXFLAGS: %s
#cgo LDFLAGS: %s
*/
import "C"

type (run_build_sh int)
`, flags.cpp, flags.cxx, flags.ld)
}

func runGoWithLLVMEnv(args []string, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags string, packages []pkg) {
	args = addTag(args, "byollvm")

	srcdir := llvmConfig("--src-root")

	tmpgopath, err := ioutil.TempDir("", "gopath")
	if err != nil {
		panic(err.Error())
	}

	for _, p := range packages {
		path := filepath.Join(tmpgopath, "src", p.pkgpath)
		err := os.MkdirAll(filepath.Dir(path), os.ModePerm)
		if err != nil {
			panic(err.Error())
		}

		abspath := p.llvmpath
		if !filepath.IsAbs(abspath) {
			abspath = filepath.Join(srcdir, abspath)
		}

		err = os.Symlink(abspath, path)
		if err != nil {
			panic(err.Error())
		}
	}

	newpath := os.Getenv("PATH")

	newgopathlist := []string{tmpgopath}
	newgopathlist = append(newgopathlist, filepath.SplitList(os.Getenv("GOPATH"))...)
	newgopath := strings.Join(newgopathlist, string(filepath.ListSeparator))

	flags := llvmFlags()

	newenv := []string{
		"CC=" + cc,
		"CXX=" + cxx,
		"CGO_CPPFLAGS=" + flags.cpp + " " + cppflags,
		"CGO_CXXFLAGS=" + flags.cxx + " " + cxxflags,
		"CGO_LDFLAGS=" + flags.ld + " " + ldflags,
		"GOPATH=" + newgopath,
		"PATH=" + newpath,
	}
	if llgo != "" {
		newenv = append(newenv, "GCCGO="+llgo)
	}

	for _, v := range os.Environ() {
		if !strings.HasPrefix(v, "CC=") &&
			!strings.HasPrefix(v, "CXX=") &&
			!strings.HasPrefix(v, "CGO_CPPFLAGS=") &&
			!strings.HasPrefix(v, "CGO_CXXFLAGS=") &&
			!strings.HasPrefix(v, "CGO_LDFLAGS=") &&
			!strings.HasPrefix(v, "GCCGO=") &&
			!strings.HasPrefix(v, "GOPATH=") &&
			!strings.HasPrefix(v, "PATH=") {
			newenv = append(newenv, v)
		}
	}

	gocmdpath, err := exec.LookPath(gocmd)
	if err != nil {
		panic(err.Error())
	}

	proc, err := os.StartProcess(gocmdpath, append([]string{gocmd}, args...),
		&os.ProcAttr{
			Env:   newenv,
			Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},
		})
	if err != nil {
		panic(err.Error())
	}
	ps, err := proc.Wait()
	if err != nil {
		panic(err.Error())
	}

	os.RemoveAll(tmpgopath)

	if !ps.Success() {
		os.Exit(1)
	}
}

func usage() {
	fmt.Println(`Usage: llvm-go subcommand [flags]

Available subcommands: build get install run test print-components print-config`)
	os.Exit(0)
}

func main() {
	cc := os.Getenv("CC")
	cxx := os.Getenv("CXX")
	cppflags := os.Getenv("CGO_CPPFLAGS")
	cxxflags := os.Getenv("CGO_CXXFLAGS")
	ldflags := os.Getenv("CGO_LDFLAGS")
	gocmd := "go"
	llgo := ""
	packagesString := ""

	flags := []struct {
		name string
		dest *string
	}{
		{"cc", &cc},
		{"cxx", &cxx},
		{"go", &gocmd},
		{"llgo", &llgo},
		{"cppflags", &cppflags},
		{"ldflags", &ldflags},
		{"packages", &packagesString},
	}

	args := os.Args[1:]
LOOP:
	for {
		if len(args) == 0 {
			usage()
		}
		for _, flag := range flags {
			if strings.HasPrefix(args[0], flag.name+"=") {
				*flag.dest = args[0][len(flag.name)+1:]
				args = args[1:]
				continue LOOP
			}
		}
		break
	}

	packages := packages
	if packagesString != "" {
		for _, field := range strings.Fields(packagesString) {
			pos := strings.IndexRune(field, '=')
			if pos == -1 {
				fmt.Fprintf(os.Stderr, "invalid packages value %q, expected 'pkgpath=llvmpath [pkgpath=llvmpath ...]'\n", packagesString)
				os.Exit(1)
			}
			packages = append(packages, pkg{
				pkgpath:  field[:pos],
				llvmpath: field[pos+1:],
			})
		}
	}

	switch args[0] {
	case "build", "get", "install", "run", "test":
		runGoWithLLVMEnv(args, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags, packages)
	case "print-components":
		printComponents()
	case "print-config":
		printConfig()
	default:
		usage()
	}
}
