// 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

import (
	"bytes"
	"io/fs"
	"os"
	"os/exec"
	"path/filepath"
	"reflect"
	"regexp"
	"runtime"
	"slices"
	"strings"
	"testing"
)

func testGOROOT(t *testing.T) string {
	goroot := runtime.GOROOT()
	if goroot == "" {
		cmd := exec.Command("go", "env", "GOROOT")
		var stderr bytes.Buffer
		cmd.Stderr = &stderr
		out, err := cmd.Output()
		goroot = string(bytes.TrimSpace(out))
		if err != nil || goroot == "" {
			t.Fatalf("go env GOROOT: %v\n%s", err, stderr.Bytes())
		}
	}
	return goroot
}

func TestGitIgnored(t *testing.T) {
	goroot := testGOROOT(t)
	_, err := os.Stat(filepath.Join(goroot, ".git"))
	if err != nil {
		t.Skipf("no $GOROOT/.git: %v", err)
	}

	m := map[string]string{
		filepath.Join(goroot, "bin/godoc"):       "x",
		filepath.Join(goroot, "bin/gofmt"):       "x",
		filepath.Join(goroot, "src/math/sin.go"): "x",
	}
	want := []string{
		filepath.Join(goroot, "bin/godoc"),
		filepath.Join(goroot, "bin/gofmt"),
	}
	t.Logf("goroot: %s", goroot)
	ignored := gitIgnored(goroot, m)
	slices.Sort(ignored)
	if !reflect.DeepEqual(ignored, want) {
		t.Errorf("gitIgnored: wrong results\nhave %v\nwant %v", ignored, want)
	}
}

func TestIsGoToolDistGenerated(t *testing.T) {
	// This test verifies that all of the files reported by isGoToolDistGenerated
	// are marked as generated by dist and vice-versa.
	// This is the regexp given for such files by https://go.dev/s/generatedcode.
	generatedRE := regexp.MustCompile(`^// Code generated by .*dist.*; DO NOT EDIT\.\n`)

	// Add a trailing separator to follow GOROOT/src if is a symlink, as is
	// apparently the case for some third-party distributions of the toolchain.
	goroot := testGOROOT(t)
	gorootSrc := filepath.Join(goroot, "src") + string(filepath.Separator)
	t.Logf("Checking generated files in %s.", gorootSrc)

	err := filepath.WalkDir(gorootSrc, func(path string, d fs.DirEntry, err error) error {
		if err != nil {
			return err
		}

		rel, err := filepath.Rel(goroot, path)
		if err != nil {
			return err
		}
		rel = filepath.ToSlash(rel)

		got := isGoToolDistGenerated(rel)

		if d.IsDir() {
			if got {
				t.Errorf("isGoToolDistGenerated(%q) = true, but %q is a directory", rel, rel)
			}
			return nil
		}

		if !got && !strings.HasPrefix(filepath.Base(path), "z") {
			// By convention, fles generated by cmd/dist always have names starting with "z".
			// If other files aren't matched by isGoToolDistGenerated, don't bother reading
			// them to check.
			return nil
		}

		b, err := os.ReadFile(path)
		if err != nil {
			return err
		}

		match := generatedRE.Find(b)
		if match == nil {
			if got {
				t.Errorf("isGoToolDistGenerated(%q) = true; want false\n(no match for %v)", rel, generatedRE)
			}
		} else {
			if !got || testing.Verbose() {
				t.Logf("%s: %q", rel, match)
			}
			if !got {
				t.Errorf("isGoToolDistGenerated(%q) = false; want true", rel)
			}
		}
		return nil
	})
	if err != nil {
		t.Error(err)
	}
}
