// 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 go1.12
// +build go1.12

package unitchecker_test

// This test depends on features such as
// go vet's support for vetx files (1.11) and
// the (*os.ProcessState).ExitCode method (1.12).

import (
	"flag"
	"os"
	"os/exec"
	"regexp"
	"runtime"
	"strings"
	"testing"

	"golang.org/x/tools/go/analysis/passes/findcall"
	"golang.org/x/tools/go/analysis/passes/printf"
	"golang.org/x/tools/go/analysis/unitchecker"
	"golang.org/x/tools/go/packages/packagestest"
)

func TestMain(m *testing.M) {
	if os.Getenv("UNITCHECKER_CHILD") == "1" {
		// child process
		main()
		panic("unreachable")
	}

	flag.Parse()
	os.Exit(m.Run())
}

func main() {
	unitchecker.Main(
		findcall.Analyzer,
		printf.Analyzer,
	)
}

// This is a very basic integration test of modular
// analysis with facts using unitchecker under "go vet".
// It fork/execs the main function above.
func TestIntegration(t *testing.T) { packagestest.TestAll(t, testIntegration) }
func testIntegration(t *testing.T, exporter packagestest.Exporter) {
	if runtime.GOOS != "linux" && runtime.GOOS != "darwin" {
		t.Skipf("skipping fork/exec test on this platform")
	}

	exported := packagestest.Export(t, exporter, []packagestest.Module{{
		Name: "golang.org/fake",
		Files: map[string]interface{}{
			"a/a.go": `package a

func _() {
	MyFunc123()
}

func MyFunc123() {}
`,
			"b/b.go": `package b

import "golang.org/fake/a"

func _() {
	a.MyFunc123()
	MyFunc123()
}

func MyFunc123() {}
`,
		}}})
	defer exported.Cleanup()

	const wantA = `# golang.org/fake/a
([/._\-a-zA-Z0-9]+[\\/]fake[\\/])?a/a.go:4:11: call of MyFunc123\(...\)
`
	const wantB = `# golang.org/fake/b
([/._\-a-zA-Z0-9]+[\\/]fake[\\/])?b/b.go:6:13: call of MyFunc123\(...\)
([/._\-a-zA-Z0-9]+[\\/]fake[\\/])?b/b.go:7:11: call of MyFunc123\(...\)
`
	const wantAJSON = `# golang.org/fake/a
\{
	"golang.org/fake/a": \{
		"findcall": \[
			\{
				"posn": "([/._\-a-zA-Z0-9]+[\\/]fake[\\/])?a/a.go:4:11",
				"message": "call of MyFunc123\(...\)"
			\}
		\]
	\}
\}
`

	for _, test := range []struct {
		args     string
		wantOut  string
		wantExit int
	}{
		{args: "golang.org/fake/a", wantOut: wantA, wantExit: 2},
		{args: "golang.org/fake/b", wantOut: wantB, wantExit: 2},
		{args: "golang.org/fake/a golang.org/fake/b", wantOut: wantA + wantB, wantExit: 2},
		{args: "-json golang.org/fake/a", wantOut: wantAJSON, wantExit: 0},
		{args: "-c=0 golang.org/fake/a", wantOut: wantA + "4		MyFunc123\\(\\)\n", wantExit: 2},
	} {
		cmd := exec.Command("go", "vet", "-vettool="+os.Args[0], "-findcall.name=MyFunc123")
		cmd.Args = append(cmd.Args, strings.Fields(test.args)...)
		cmd.Env = append(exported.Config.Env, "UNITCHECKER_CHILD=1")
		cmd.Dir = exported.Config.Dir

		out, err := cmd.CombinedOutput()
		exitcode := 0
		if exitErr, ok := err.(*exec.ExitError); ok {
			exitcode = exitErr.ExitCode()
		}
		if exitcode != test.wantExit {
			t.Errorf("%s: got exit code %d, want %d", test.args, exitcode, test.wantExit)
		}

		matched, err := regexp.Match(test.wantOut, out)
		if err != nil {
			t.Fatal(err)
		}
		if !matched {
			t.Errorf("%s: got <<%s>>, want match of regexp <<%s>>", test.args, out, test.wantOut)
		}
	}
}
