// Copyright 2018 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.

//go:build ignore
// +build ignore

// Generate system call table for DragonFly, NetBSD,
// FreeBSD or OpenBSD from master list (for example,
// /usr/src/sys/kern/syscalls.master or sys/syscall.h).
package main

import (
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"regexp"
	"strings"
)

var (
	goos, goarch string
)

// cmdLine returns this programs's commandline arguments
func cmdLine() string {
	return "go run mksysnum.go " + strings.Join(os.Args[1:], " ")
}

// goBuildTags returns build tags in the go:build format.
func goBuildTags() string {
	return fmt.Sprintf("%s && %s", goarch, goos)
}

// plusBuildTags returns build tags in the +build format.
func plusBuildTags() string {
	return fmt.Sprintf("%s,%s", goarch, goos)
}

func checkErr(err error) {
	if err != nil {
		fmt.Fprintf(os.Stderr, "%v\n", err)
		os.Exit(1)
	}
}

// source string and substring slice for regexp
type re struct {
	str string   // source string
	sub []string // matched sub-string
}

// Match performs regular expression match
func (r *re) Match(exp string) bool {
	r.sub = regexp.MustCompile(exp).FindStringSubmatch(r.str)
	if r.sub != nil {
		return true
	}
	return false
}

// fetchFile fetches a text file from URL
func fetchFile(URL string) io.Reader {
	resp, err := http.Get(URL)
	checkErr(err)
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	checkErr(err)
	return strings.NewReader(string(body))
}

// readFile reads a text file from path
func readFile(path string) io.Reader {
	file, err := os.Open(os.Args[1])
	checkErr(err)
	return file
}

func format(name, num, proto string) string {
	name = strings.ToUpper(name)
	// There are multiple entries for enosys and nosys, so comment them out.
	nm := re{str: name}
	if nm.Match(`^SYS_E?NOSYS$`) {
		name = fmt.Sprintf("// %s", name)
	}
	if name == `SYS_SYS_EXIT` {
		name = `SYS_EXIT`
	}
	return fmt.Sprintf("	%s = %s;  // %s\n", name, num, proto)
}

func main() {
	// Get the OS (using GOOS_TARGET if it exist)
	goos = os.Getenv("GOOS_TARGET")
	if goos == "" {
		goos = os.Getenv("GOOS")
	}
	// Get the architecture (using GOARCH_TARGET if it exists)
	goarch = os.Getenv("GOARCH_TARGET")
	if goarch == "" {
		goarch = os.Getenv("GOARCH")
	}
	// Check if GOOS and GOARCH environment variables are defined
	if goarch == "" || goos == "" {
		fmt.Fprintf(os.Stderr, "GOARCH or GOOS not defined in environment\n")
		os.Exit(1)
	}

	file := strings.TrimSpace(os.Args[1])
	var syscalls io.Reader
	if strings.HasPrefix(file, "https://") || strings.HasPrefix(file, "http://") {
		// Download syscalls.master file
		syscalls = fetchFile(file)
	} else {
		syscalls = readFile(file)
	}

	var text, line string
	s := bufio.NewScanner(syscalls)
	for s.Scan() {
		t := re{str: line}
		if t.Match(`^(.*)\\$`) {
			// Handle continuation
			line = t.sub[1]
			line += strings.TrimLeft(s.Text(), " \t")
		} else {
			// New line
			line = s.Text()
		}
		t = re{str: line}
		if t.Match(`\\$`) {
			continue
		}
		t = re{str: line}

		switch goos {
		case "dragonfly":
			if t.Match(`^([0-9]+)\s+STD\s+({ \S+\s+(\w+).*)$`) {
				num, proto := t.sub[1], t.sub[2]
				name := fmt.Sprintf("SYS_%s", t.sub[3])
				text += format(name, num, proto)
			}
		case "freebsd":
			if t.Match(`^([0-9]+)\s+\S+\s+(?:(?:NO)?STD|COMPAT10)\s+({ \S+\s+(\w+).*)$`) {
				num, proto := t.sub[1], t.sub[2]
				name := fmt.Sprintf("SYS_%s", t.sub[3])
				text += format(name, num, proto)
			}
		case "openbsd":
			if t.Match(`^([0-9]+)\s+STD\s+(NOLOCK\s+)?({ \S+\s+\*?(\w+).*)$`) {
				num, proto, name := t.sub[1], t.sub[3], t.sub[4]
				text += format(name, num, proto)
			}
		case "netbsd":
			if t.Match(`^([0-9]+)\s+((STD)|(NOERR))\s+(RUMP\s+)?({\s+\S+\s*\*?\s*\|(\S+)\|(\S*)\|(\w+).*\s+})(\s+(\S+))?$`) {
				num, proto, compat := t.sub[1], t.sub[6], t.sub[8]
				name := t.sub[7] + "_" + t.sub[9]
				if t.sub[11] != "" {
					name = t.sub[7] + "_" + t.sub[11]
				}
				name = strings.ToUpper(name)
				if compat == "" || compat == "13" || compat == "30" || compat == "50" {
					text += fmt.Sprintf("	%s = %s;  // %s\n", name, num, proto)
				}
			}
		default:
			fmt.Fprintf(os.Stderr, "unrecognized GOOS=%s\n", goos)
			os.Exit(1)

		}
	}
	err := s.Err()
	checkErr(err)

	fmt.Printf(template, cmdLine(), goBuildTags(), plusBuildTags(), text)
}

const template = `// %s
// Code generated by the command above; see README.md. DO NOT EDIT.

//go:build %s
// +build %s

package unix

const(
%s)`
