// Copyright 2020 The SwiftShader Authors. All Rights Reserved.
//
// 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.

// Package llvm provides functions and types for locating and using the llvm
// toolchains.
package llvm

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"runtime"
	"sort"
	"strconv"

	"../util"
)

const maxLLVMVersion = 10

// Version holds the build version information of an LLVM toolchain.
type Version struct {
	Major, Minor, Point int
}

func (v Version) String() string {
	return fmt.Sprintf("%v.%v.%v", v.Major, v.Minor, v.Point)
}

// GreaterEqual returns true if v >= rhs.
func (v Version) GreaterEqual(rhs Version) bool {
	if v.Major > rhs.Major {
		return true
	}
	if v.Major < rhs.Major {
		return false
	}
	if v.Minor > rhs.Minor {
		return true
	}
	if v.Minor < rhs.Minor {
		return false
	}
	return v.Point >= rhs.Point
}

// Download downloads and verifies the LLVM toolchain for the current OS.
func (v Version) Download() ([]byte, error) {
	return v.DownloadForOS(runtime.GOOS)
}

// DownloadForOS downloads and verifies the LLVM toolchain for the given OS.
func (v Version) DownloadForOS(osName string) ([]byte, error) {
	url, sig, key, err := v.DownloadInfoForOS(osName)
	if err != nil {
		return nil, err
	}

	resp, err := http.Get(url)
	if err != nil {
		return nil, fmt.Errorf("Could not download LLVM from %v: %v", url, err)
	}
	defer resp.Body.Close()

	content, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("Could not download LLVM from %v: %v", url, err)
	}

	sigfile, err := os.Open(sig)
	if err != nil {
		return nil, fmt.Errorf("Couldn't open file '%s': %v", sig, err)
	}
	defer sigfile.Close()

	keyfile, err := os.Open(key)
	if err != nil {
		return nil, fmt.Errorf("Couldn't open file '%s': %v", key, err)
	}
	defer keyfile.Close()

	if err := util.CheckPGP(bytes.NewReader(content), sigfile, keyfile); err != nil {
		return nil, err
	}
	return content, nil
}

// DownloadInfoForOS returns the download url, signature and key for the given
// LLVM version for the given OS.
func (v Version) DownloadInfoForOS(os string) (url, sig, key string, err error) {
	switch v {
	case Version{10, 0, 0}:
		key = relfile("10.0.0.pub.key")
		switch os {
		case "linux":
			url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz"
			sig = relfile("10.0.0-ubuntu.sig")
			return
		case "darwin":
			url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/clang+llvm-10.0.0-x86_64-apple-darwin.tar.xz"
			sig = relfile("10.0.0-darwin.sig")
			return
		case "windows":
			url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/LLVM-10.0.0-win64.exe"
			sig = relfile("10.0.0-win64.sig")
			return
		default:
			return "", "", "", fmt.Errorf("Unsupported OS: %v", os)
		}
	default:
		return "", "", "", fmt.Errorf("Unknown download for LLVM %v", v)
	}
}
func relfile(path string) string {
	_, thisFile, _, _ := runtime.Caller(1)
	thisDir := filepath.Dir(thisFile)
	return filepath.Join(thisDir, path)
}

// Toolchain holds the paths and version information about an LLVM toolchain.
type Toolchain struct {
	Version Version
	BinDir  string
}

// Toolchains is a list of Toolchain
type Toolchains []Toolchain

// Find looks for a toolchain with the specific version.
func (l Toolchains) Find(v Version) *Toolchain {
	for _, t := range l {
		if t.Version == v {
			return &t
		}
	}
	return nil
}

// FindAtLeast looks for a toolchain with the given version, returning the highest found version.
func (l Toolchains) FindAtLeast(v Version) *Toolchain {
	out := (*Toolchain)(nil)
	for _, t := range l {
		if t.Version.GreaterEqual(v) && (out == nil || out.Version.GreaterEqual(t.Version)) {
			t := t
			out = &t
		}
	}
	return out
}

// Search looks for llvm toolchains in paths.
// If paths is empty, then PATH is searched.
func Search(paths ...string) Toolchains {
	toolchains := map[Version]Toolchain{}
	search := func(name string) {
		if len(paths) > 0 {
			for _, path := range paths {
				if util.IsFile(path) {
					path = filepath.Dir(path)
				}
				if t := toolchain(path); t != nil {
					toolchains[t.Version] = *t
					continue
				}
				if t := toolchain(filepath.Join(path, "bin")); t != nil {
					toolchains[t.Version] = *t
					continue
				}
			}
		} else {
			path, err := exec.LookPath(name)
			if err == nil {
				if t := toolchain(filepath.Dir(path)); t != nil {
					toolchains[t.Version] = *t
				}
			}
		}
	}

	search("clang")
	for i := 8; i < maxLLVMVersion; i++ {
		search(fmt.Sprintf("clang-%d", i))
	}

	out := make([]Toolchain, 0, len(toolchains))
	for _, t := range toolchains {
		out = append(out, t)
	}
	sort.Slice(out, func(i, j int) bool { return out[i].Version.GreaterEqual(out[j].Version) })

	return out
}

// Clang returns the path to the clang executable.
func (t Toolchain) Clang() string {
	return filepath.Join(t.BinDir, "clang"+exeExt())
}

// ClangXX returns the path to the clang++ executable.
func (t Toolchain) ClangXX() string {
	return filepath.Join(t.BinDir, "clang++"+exeExt())
}

// Cov returns the path to the llvm-cov executable.
func (t Toolchain) Cov() string {
	return filepath.Join(t.BinDir, "llvm-cov"+exeExt())
}

// Profdata returns the path to the llvm-profdata executable.
func (t Toolchain) Profdata() string {
	return filepath.Join(t.BinDir, "llvm-profdata"+exeExt())
}

func toolchain(dir string) *Toolchain {
	t := Toolchain{BinDir: dir}
	if t.resolve() {
		return &t
	}
	return nil
}

func (t *Toolchain) resolve() bool {
	if !util.IsFile(t.Profdata()) { // llvm-profdata doesn't have --version flag
		return false
	}
	version, ok := parseVersion(t.Cov())
	t.Version = version
	return ok
}

func exeExt() string {
	switch runtime.GOOS {
	case "windows":
		return ".exe"
	default:
		return ""
	}
}

var versionRE = regexp.MustCompile(`(?:clang|LLVM) version ([0-9]+)\.([0-9]+)\.([0-9]+)`)

func parseVersion(tool string) (Version, bool) {
	out, err := exec.Command(tool, "--version").Output()
	if err != nil {
		return Version{}, false
	}
	matches := versionRE.FindStringSubmatch(string(out))
	if len(matches) < 4 {
		return Version{}, false
	}
	major, majorErr := strconv.Atoi(matches[1])
	minor, minorErr := strconv.Atoi(matches[2])
	point, pointErr := strconv.Atoi(matches[3])
	if majorErr != nil || minorErr != nil || pointErr != nil {
		return Version{}, false
	}
	return Version{major, minor, point}, true
}
