// Copyright 2023 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 main_test

import (
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"
	"testing"

	"golang.org/x/tools/internal/testenv"
	"golang.org/x/tools/txtar"
)

// Test runs the deadcode command on each scenario
// described by a testdata/*.txtar file.
func Test(t *testing.T) {
	testenv.NeedsTool(t, "go")
	if runtime.GOOS == "android" {
		t.Skipf("the dependencies are not available on android")
	}

	exe := buildDeadcode(t)

	matches, err := filepath.Glob("testdata/*.txtar")
	if err != nil {
		t.Fatal(err)
	}
	for _, filename := range matches {
		t.Run(filename, func(t *testing.T) {
			t.Parallel()

			ar, err := txtar.ParseFile(filename)
			if err != nil {
				t.Fatal(err)
			}

			// Write the archive files to the temp directory.
			tmpdir := t.TempDir()
			for _, f := range ar.Files {
				filename := filepath.Join(tmpdir, f.Name)
				if err := os.MkdirAll(filepath.Dir(filename), 0777); err != nil {
					t.Fatal(err)
				}
				if err := os.WriteFile(filename, f.Data, 0666); err != nil {
					t.Fatal(err)
				}
			}

			// Parse archive comment as directives of these forms:
			//
			//  [!]deadcode args...	command-line arguments
			//  [!]want arg		expected/unwanted string in output (or stderr)
			//
			// Args may be Go-quoted strings.
			type testcase struct {
				linenum int
				args    []string
				wantErr bool
				want    map[string]bool // string -> sense
			}
			var cases []*testcase
			var current *testcase
			for i, line := range strings.Split(string(ar.Comment), "\n") {
				line = strings.TrimSpace(line)
				if line == "" || line[0] == '#' {
					continue // skip blanks and comments
				}

				words, err := words(line)
				if err != nil {
					t.Fatalf("cannot break line into words: %v (%s)", err, line)
				}
				switch kind := words[0]; kind {
				case "deadcode", "!deadcode":
					current = &testcase{
						linenum: i + 1,
						want:    make(map[string]bool),
						args:    words[1:],
						wantErr: kind[0] == '!',
					}
					cases = append(cases, current)
				case "want", "!want":
					if current == nil {
						t.Fatalf("'want' directive must be after 'deadcode'")
					}
					if len(words) != 2 {
						t.Fatalf("'want' directive needs argument <<%s>>", line)
					}
					current.want[words[1]] = kind[0] != '!'
				default:
					t.Fatalf("%s: invalid directive %q", filename, kind)
				}
			}

			for _, tc := range cases {
				t.Run(fmt.Sprintf("L%d", tc.linenum), func(t *testing.T) {
					// Run the command.
					cmd := exec.Command(exe, tc.args...)
					cmd.Stdout = new(bytes.Buffer)
					cmd.Stderr = new(bytes.Buffer)
					cmd.Dir = tmpdir
					cmd.Env = append(os.Environ(), "GOPROXY=", "GO111MODULE=on")
					var got string
					if err := cmd.Run(); err != nil {
						if !tc.wantErr {
							t.Fatalf("deadcode failed: %v (stderr=%s)", err, cmd.Stderr)
						}
						got = fmt.Sprint(cmd.Stderr)
					} else {
						if tc.wantErr {
							t.Fatalf("deadcode succeeded unexpectedly (stdout=%s)", cmd.Stdout)
						}
						got = fmt.Sprint(cmd.Stdout)
					}

					// Check each want directive.
					for str, sense := range tc.want {
						ok := true
						if strings.Contains(got, str) != sense {
							if sense {
								t.Errorf("missing %q", str)
							} else {
								t.Errorf("unwanted %q", str)
							}
							ok = false
						}
						if !ok {
							t.Errorf("got: <<%s>>", got)
						}
					}
				})
			}
		})
	}
}

// buildDeadcode builds the deadcode executable.
// It returns its path, and a cleanup function.
func buildDeadcode(t *testing.T) string {
	bin := filepath.Join(t.TempDir(), "deadcode")
	if runtime.GOOS == "windows" {
		bin += ".exe"
	}
	cmd := exec.Command("go", "build", "-o", bin)
	if out, err := cmd.CombinedOutput(); err != nil {
		t.Fatalf("Building deadcode: %v\n%s", err, out)
	}
	return bin
}

// words breaks a string into words, respecting
// Go string quotations around words with spaces.
func words(s string) ([]string, error) {
	var words []string
	for s != "" {
		s = strings.TrimSpace(s)
		var word string
		if s[0] == '"' || s[0] == '`' {
			prefix, err := strconv.QuotedPrefix(s)
			if err != nil {
				return nil, err
			}
			s = s[len(prefix):]
			word, _ = strconv.Unquote(prefix)
		} else {
			prefix, rest, _ := strings.Cut(s, " ")
			s = rest
			word = prefix
		}
		words = append(words, word)
	}
	return words, nil
}
