// 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"
	"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 := io.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)\s+({ \S+\s+(\w+).*)$`) {
				num, proto := t.sub[1], t.sub[2]
				name := fmt.Sprintf("SYS_%s", t.sub[3])
				// remove whitespace around parens
				proto = regexp.MustCompile(`\( `).ReplaceAllString(proto, "(")
				proto = regexp.MustCompile(` \)`).ReplaceAllString(proto, ")")
				// remove SAL 2.0 annotations
				proto = regexp.MustCompile(`_In[^ ]*[_)] `).ReplaceAllString(proto, "")
				proto = regexp.MustCompile(`_Out[^ ]*[_)] `).ReplaceAllString(proto, "")
				// remove double spaces at the source
				proto = regexp.MustCompile(`\s{2}`).ReplaceAllString(proto, " ")
				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)`
