// Copyright 2022 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 vcweb

import (
	"bufio"
	"bytes"
	"cmd/internal/script"
	"context"
	"errors"
	"fmt"
	"internal/txtar"
	"io"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"time"

	"golang.org/x/mod/module"
	"golang.org/x/mod/semver"
	"golang.org/x/mod/zip"
)

// newScriptEngine returns a script engine augmented with commands for
// reproducing version-control repositories by replaying commits.
func newScriptEngine() *script.Engine {
	conds := script.DefaultConds()

	add := func(name string, cond script.Cond) {
		if _, ok := conds[name]; ok {
			panic(fmt.Sprintf("condition %q is already registered", name))
		}
		conds[name] = cond
	}
	add("git-sha256", script.OnceCondition("the local 'git' version is recent enough to support sha256 object/commit hashes", gitSupportsSHA256))

	interrupt := func(cmd *exec.Cmd) error { return cmd.Process.Signal(os.Interrupt) }
	gracePeriod := 30 * time.Second // arbitrary

	cmds := script.DefaultCmds()
	cmds["at"] = scriptAt()
	cmds["fossil"] = script.Program("fossil", interrupt, gracePeriod)
	cmds["git"] = script.Program("git", interrupt, gracePeriod)
	cmds["hg"] = script.Program("hg", interrupt, gracePeriod)
	cmds["handle"] = scriptHandle()
	cmds["modzip"] = scriptModzip()
	cmds["skip"] = scriptSkip()
	cmds["status"] = scriptStatus()
	cmds["svnadmin"] = script.Program("svnadmin", interrupt, gracePeriod)
	cmds["svn"] = script.Program("svn", interrupt, gracePeriod)
	cmds["unquote"] = scriptUnquote()

	return &script.Engine{
		Cmds:  cmds,
		Conds: conds,
	}
}

// loadScript interprets the given script content using the vcweb script engine.
// loadScript always returns either a non-nil handler or a non-nil error.
//
// The script content must be a txtar archive with a comment containing a script
// with exactly one "handle" command and zero or more VCS commands to prepare
// the repository to be served.
func (s *Server) loadScript(ctx context.Context, logger *log.Logger, scriptPath string, scriptContent []byte, workDir string) (http.Handler, error) {
	ar := txtar.Parse(scriptContent)

	if err := os.MkdirAll(workDir, 0755); err != nil {
		return nil, err
	}

	st, err := s.newState(ctx, workDir)
	if err != nil {
		return nil, err
	}
	if err := st.ExtractFiles(ar); err != nil {
		return nil, err
	}

	scriptName := filepath.Base(scriptPath)
	scriptLog := new(strings.Builder)
	err = s.engine.Execute(st, scriptName, bufio.NewReader(bytes.NewReader(ar.Comment)), scriptLog)
	closeErr := st.CloseAndWait(scriptLog)
	logger.Printf("%s:", scriptName)
	io.WriteString(logger.Writer(), scriptLog.String())
	io.WriteString(logger.Writer(), "\n")
	if err != nil {
		return nil, err
	}
	if closeErr != nil {
		return nil, err
	}

	sc, err := getScriptCtx(st)
	if err != nil {
		return nil, err
	}
	if sc.handler == nil {
		return nil, errors.New("script completed without setting handler")
	}
	return sc.handler, nil
}

// newState returns a new script.State for executing scripts in workDir.
func (s *Server) newState(ctx context.Context, workDir string) (*script.State, error) {
	ctx = &scriptCtx{
		Context: ctx,
		server:  s,
	}

	st, err := script.NewState(ctx, workDir, s.env)
	if err != nil {
		return nil, err
	}
	return st, nil
}

// scriptEnviron returns a new environment that attempts to provide predictable
// behavior for the supported version-control tools.
func scriptEnviron(homeDir string) []string {
	env := []string{
		"USER=gopher",
		homeEnvName() + "=" + homeDir,
		"GIT_CONFIG_NOSYSTEM=1",
		"HGRCPATH=" + filepath.Join(homeDir, ".hgrc"),
		"HGENCODING=utf-8",
	}
	// Preserve additional environment variables that may be needed by VCS tools.
	for _, k := range []string{
		pathEnvName(),
		tempEnvName(),
		"SYSTEMROOT",        // must be preserved on Windows to find DLLs; golang.org/issue/25210
		"WINDIR",            // must be preserved on Windows to be able to run PowerShell command; golang.org/issue/30711
		"ComSpec",           // must be preserved on Windows to be able to run Batch files; golang.org/issue/56555
		"DYLD_LIBRARY_PATH", // must be preserved on macOS systems to find shared libraries
		"LD_LIBRARY_PATH",   // must be preserved on Unix systems to find shared libraries
		"LIBRARY_PATH",      // allow override of non-standard static library paths
		"PYTHONPATH",        // may be needed by hg to find imported modules
	} {
		if v, ok := os.LookupEnv(k); ok {
			env = append(env, k+"="+v)
		}
	}

	if os.Getenv("GO_BUILDER_NAME") != "" || os.Getenv("GIT_TRACE_CURL") == "1" {
		// To help diagnose https://go.dev/issue/52545,
		// enable tracing for Git HTTPS requests.
		env = append(env,
			"GIT_TRACE_CURL=1",
			"GIT_TRACE_CURL_NO_DATA=1",
			"GIT_REDACT_COOKIES=o,SSO,GSSO_Uberproxy")
	}

	return env
}

// homeEnvName returns the environment variable used by os.UserHomeDir
// to locate the user's home directory.
func homeEnvName() string {
	switch runtime.GOOS {
	case "windows":
		return "USERPROFILE"
	case "plan9":
		return "home"
	default:
		return "HOME"
	}
}

// tempEnvName returns the environment variable used by os.TempDir
// to locate the default directory for temporary files.
func tempEnvName() string {
	switch runtime.GOOS {
	case "windows":
		return "TMP"
	case "plan9":
		return "TMPDIR" // actually plan 9 doesn't have one at all but this is fine
	default:
		return "TMPDIR"
	}
}

// pathEnvName returns the environment variable used by exec.LookPath to
// identify directories to search for executables.
func pathEnvName() string {
	switch runtime.GOOS {
	case "plan9":
		return "path"
	default:
		return "PATH"
	}
}

// A scriptCtx is a context.Context that stores additional state for script
// commands.
type scriptCtx struct {
	context.Context
	server      *Server
	commitTime  time.Time
	handlerName string
	handler     http.Handler
}

// scriptCtxKey is the key associating the *scriptCtx in a script's Context..
type scriptCtxKey struct{}

func (sc *scriptCtx) Value(key any) any {
	if key == (scriptCtxKey{}) {
		return sc
	}
	return sc.Context.Value(key)
}

func getScriptCtx(st *script.State) (*scriptCtx, error) {
	sc, ok := st.Context().Value(scriptCtxKey{}).(*scriptCtx)
	if !ok {
		return nil, errors.New("scriptCtx not found in State.Context")
	}
	return sc, nil
}

func scriptAt() script.Cmd {
	return script.Command(
		script.CmdUsage{
			Summary: "set the current commit time for all version control systems",
			Args:    "time",
			Detail: []string{
				"The argument must be an absolute timestamp in RFC3339 format.",
			},
		},
		func(st *script.State, args ...string) (script.WaitFunc, error) {
			if len(args) != 1 {
				return nil, script.ErrUsage
			}

			sc, err := getScriptCtx(st)
			if err != nil {
				return nil, err
			}

			sc.commitTime, err = time.ParseInLocation(time.RFC3339, args[0], time.UTC)
			if err == nil {
				st.Setenv("GIT_COMMITTER_DATE", args[0])
				st.Setenv("GIT_AUTHOR_DATE", args[0])
			}
			return nil, err
		})
}

func scriptHandle() script.Cmd {
	return script.Command(
		script.CmdUsage{
			Summary: "set the HTTP handler that will serve the script's output",
			Args:    "handler [dir]",
			Detail: []string{
				"The handler will be passed the script's current working directory and environment as arguments.",
				"Valid handlers include 'dir' (for general http.Dir serving), 'fossil', 'git', and 'hg'",
			},
		},
		func(st *script.State, args ...string) (script.WaitFunc, error) {
			if len(args) == 0 || len(args) > 2 {
				return nil, script.ErrUsage
			}

			sc, err := getScriptCtx(st)
			if err != nil {
				return nil, err
			}

			if sc.handler != nil {
				return nil, fmt.Errorf("server handler already set to %s", sc.handlerName)
			}

			name := args[0]
			h, ok := sc.server.vcsHandlers[name]
			if !ok {
				return nil, fmt.Errorf("unrecognized VCS %q", name)
			}
			sc.handlerName = name
			if !h.Available() {
				return nil, ServerNotInstalledError{name}
			}

			dir := st.Getwd()
			if len(args) >= 2 {
				dir = st.Path(args[1])
			}
			sc.handler, err = h.Handler(dir, st.Environ(), sc.server.logger)
			return nil, err
		})
}

func scriptModzip() script.Cmd {
	return script.Command(
		script.CmdUsage{
			Summary: "create a Go module zip file from a directory",
			Args:    "zipfile path@version dir",
		},
		func(st *script.State, args ...string) (wait script.WaitFunc, err error) {
			if len(args) != 3 {
				return nil, script.ErrUsage
			}
			zipPath := st.Path(args[0])
			mPath, version, ok := strings.Cut(args[1], "@")
			if !ok {
				return nil, script.ErrUsage
			}
			dir := st.Path(args[2])

			if err := os.MkdirAll(filepath.Dir(zipPath), 0755); err != nil {
				return nil, err
			}
			f, err := os.Create(zipPath)
			if err != nil {
				return nil, err
			}
			defer func() {
				if closeErr := f.Close(); err == nil {
					err = closeErr
				}
			}()

			return nil, zip.CreateFromDir(f, module.Version{Path: mPath, Version: version}, dir)
		})
}

func scriptSkip() script.Cmd {
	return script.Command(
		script.CmdUsage{
			Summary: "skip the current test",
			Args:    "[msg]",
		},
		func(_ *script.State, args ...string) (script.WaitFunc, error) {
			if len(args) > 1 {
				return nil, script.ErrUsage
			}
			if len(args) == 0 {
				return nil, SkipError{""}
			}
			return nil, SkipError{args[0]}
		})
}

type statusWriter struct {
	http.ResponseWriter
	status int
}

func (w *statusWriter) WriteHeader(code int) {
	w.ResponseWriter.WriteHeader(w.status)
}

type statusCodeHandler struct {
	handler    http.Handler
	statusCode int
}

func (h *statusCodeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	h.handler.ServeHTTP(&statusWriter{ResponseWriter: w, status: h.statusCode}, r)
}

func scriptStatus() script.Cmd {
	return script.Command(
		script.CmdUsage{
			Summary: "set the HTTP status code for the handler",
			Args:    "code",
		},
		func(st *script.State, args ...string) (script.WaitFunc, error) {
			if len(args) != 1 {
				return nil, script.ErrUsage
			}
			sc, err := getScriptCtx(st)
			if err != nil {
				return nil, err
			}
			if sc.handler == nil {
				return nil, errors.New("status command must be called after handle")
			}
			code, err := strconv.Atoi(args[0])
			if err != nil {
				return nil, err
			}
			sc.handler = &statusCodeHandler{handler: sc.handler, statusCode: code}
			return nil, nil
		})
}

type SkipError struct {
	Msg string
}

func (s SkipError) Error() string {
	if s.Msg == "" {
		return "skip"
	}
	return s.Msg
}

func scriptUnquote() script.Cmd {
	return script.Command(
		script.CmdUsage{
			Summary: "unquote the argument as a Go string",
			Args:    "string",
		},
		func(st *script.State, args ...string) (script.WaitFunc, error) {
			if len(args) != 1 {
				return nil, script.ErrUsage
			}

			s, err := strconv.Unquote(`"` + args[0] + `"`)
			if err != nil {
				return nil, err
			}

			wait := func(*script.State) (stdout, stderr string, err error) {
				return s, "", nil
			}
			return wait, nil
		})
}

// Capture the major, minor and (optionally) patch version, but ignore anything later
var gitVersLineExtract = regexp.MustCompile(`git version\s+(\d+\.\d+(?:\.\d+)?)`)

func gitVersion() (string, error) {
	gitOut, runErr := exec.Command("git", "version").CombinedOutput()
	if runErr != nil {
		return "v0", fmt.Errorf("failed to execute git version: %w", runErr)
	}
	matches := gitVersLineExtract.FindSubmatch(gitOut)
	if len(matches) < 2 {
		return "v0", fmt.Errorf("git version extraction regexp did not match version line: %q", gitOut)
	}
	return "v" + string(matches[1]), nil
}

func hasAtLeastGitVersion(minVers string) (bool, error) {
	gitVers, gitVersErr := gitVersion()
	if gitVersErr != nil {
		return false, gitVersErr
	}
	return semver.Compare(minVers, gitVers) <= 0, nil
}

func gitSupportsSHA256() (bool, error) {
	return hasAtLeastGitVersion("v2.29")
}
