// Copyright 2024 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 scripttest

import (
	"bytes"
	"cmd/internal/script"
	"internal/diff"
	"internal/testenv"
	"os"
	"path/filepath"
	"strings"
	"testing"
	"text/template"
)

func checkScriptReadme(t *testing.T, engine *script.Engine, env []string, scriptspath, gotool string, fixReadme bool) {
	var args struct {
		Language   string
		Commands   string
		Conditions string
	}

	cmds := new(strings.Builder)
	if err := engine.ListCmds(cmds, true); err != nil {
		t.Fatal(err)
	}
	args.Commands = cmds.String()

	conds := new(strings.Builder)
	if err := engine.ListConds(conds, nil); err != nil {
		t.Fatal(err)
	}
	args.Conditions = conds.String()

	doc := new(strings.Builder)
	cmd := testenv.Command(t, gotool, "doc", "cmd/internal/script")
	cmd.Dir = t.TempDir() // make sure the test is not running inside the std or cmd module of another GOROOT
	cmd.Env = env
	cmd.Stdout = doc
	if err := cmd.Run(); err != nil {
		t.Fatal(cmd, ":", err)
	}
	_, lang, ok := strings.Cut(doc.String(), "# Script Language\n\n")
	if !ok {
		t.Fatalf("%q did not include Script Language section", cmd)
	}
	lang, _, ok = strings.Cut(lang, "\n\nvar ")
	if !ok {
		t.Fatalf("%q did not include vars after Script Language section", cmd)
	}
	args.Language = lang

	tmpl := template.Must(template.New("README").Parse(readmeTmpl[1:]))
	buf := new(bytes.Buffer)
	if err := tmpl.Execute(buf, args); err != nil {
		t.Fatal(err)
	}

	readmePath := filepath.Join(scriptspath, "README")
	old, err := os.ReadFile(readmePath)
	if err != nil {
		t.Fatal(err)
	}
	diff := diff.Diff(readmePath, old, "readmeTmpl", buf.Bytes())
	if diff == nil {
		t.Logf("%s is up to date.", readmePath)
		return
	}

	if fixReadme {
		if err := os.WriteFile(readmePath, buf.Bytes(), 0666); err != nil {
			t.Fatal(err)
		}
		t.Logf("wrote %d bytes to %s", buf.Len(), readmePath)
	} else {
		t.Logf("\n%s", diff)
		t.Errorf("%s is stale. To update, run 'go generate cmd/go'.", readmePath)
	}
}

const readmeTmpl = `
This file is generated by 'go generate'. DO NOT EDIT.

This directory holds test scripts *.txt run during 'go test cmd/<toolname>'.
To run a specific script foo.txt

	go test cmd/<toolname> -run=Script/^foo$

In general script files should have short names: a few words,
 not whole sentences.
The first word should be the general category of behavior being tested,
often the name of a go subcommand (build, link, compile, ...) or concept (vendor, pattern).

Each script is a text archive (go doc internal/txtar).
The script begins with an actual command script to run
followed by the content of zero or more supporting files to
create in the script's temporary file system before it starts executing.

As an example, run_hello.txt says:

	# hello world
	go run hello.go
	stderr 'hello world'
	! stdout .

	-- hello.go --
	package main
	func main() { println("hello world") }

Each script runs in a fresh temporary work directory tree, available to scripts as $WORK.
Scripts also have access to other environment variables, including:

	GOARCH=<target GOARCH>
	GOOS=<target GOOS>
	TMPDIR=$WORK/tmp
	devnull=<value of os.DevNull>
	goversion=<current Go version; for example, 1.12>

On Plan 9, the variables $path and $home are set instead of $PATH and $HOME.
On Windows, the variables $USERPROFILE and $TMP are set instead of
$HOME and $TMPDIR.

The lines at the top of the script are a sequence of commands to be executed by
a small script engine configured in .../cmd/internal/script/scripttest/run.go (not the system shell).

{{.Language}}

When TestScript runs a script and the script fails, by default TestScript shows
the execution of the most recent phase of the script (since the last # comment)
and only shows the # comments for earlier phases.

Note also that in reported output, the actual name of the per-script temporary directory
has been consistently replaced with the literal string $WORK.

The available commands are:
{{.Commands}}

The available conditions are:
{{.Conditions}}
`
