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

import (
	"context"
	"fmt"
	"path"
	"path/filepath"
	"strings"
	"testing"

	"github.com/google/go-cmp/cmp"
	"golang.org/x/tools/go/packages/packagestest"
	"golang.org/x/vuln/internal/result"
	"golang.org/x/vuln/internal/test"
	"golang.org/x/vuln/internal/vulncheck"
	"golang.org/x/vuln/osv"
)

func TestUniqueCallStack(t *testing.T) {
	a := &vulncheck.FuncNode{Name: "A"}
	b := &vulncheck.FuncNode{Name: "B"}
	v1 := &vulncheck.FuncNode{Name: "V1"}
	v2 := &vulncheck.FuncNode{Name: "V2"}
	v3 := &vulncheck.FuncNode{Name: "V3"}

	vuln1 := &vulncheck.Vuln{Symbol: "V1", CallSink: 1}
	vuln2 := &vulncheck.Vuln{Symbol: "V2", CallSink: 2}
	vuln3 := &vulncheck.Vuln{Symbol: "V3", CallSink: 3}

	vr := &vulncheck.Result{
		Calls: &vulncheck.CallGraph{
			Functions: map[int]*vulncheck.FuncNode{1: v1, 2: v2, 3: v3},
		},
		Vulns: []*vulncheck.Vuln{vuln1, vuln2, vuln3},
	}

	callStack := func(fs ...*vulncheck.FuncNode) vulncheck.CallStack {
		var cs vulncheck.CallStack
		for _, f := range fs {
			cs = append(cs, vulncheck.StackEntry{Function: f})
		}
		return cs
	}

	// V1, V2, and V3 are vulnerable symbols
	skip := []*vulncheck.Vuln{vuln1, vuln2, vuln3}
	for _, test := range []struct {
		vuln *vulncheck.Vuln
		css  []vulncheck.CallStack
		want vulncheck.CallStack
	}{
		// [A -> B -> V3 -> V1, A -> V1] ==> A -> V1 since the first stack goes through V3
		{vuln1, []vulncheck.CallStack{callStack(a, b, v3, v1), callStack(a, v1)}, callStack(a, v1)},
		// [A -> V1 -> V2] ==> nil since the only candidate call stack goes through V1
		{vuln2, []vulncheck.CallStack{callStack(a, v1, v2)}, nil},
		// [A -> V1 -> V3, A -> B -> v3] ==> A -> B -> V3 since the first stack goes through V1
		{vuln3, []vulncheck.CallStack{callStack(a, v1, v3), callStack(a, b, v3)}, callStack(a, b, v3)},
	} {
		t.Run(test.vuln.Symbol, func(t *testing.T) {
			got := uniqueCallStack(test.vuln, test.css, skip, vr)
			if diff := cmp.Diff(test.want, got); diff != "" {
				t.Fatalf("mismatch (-want, +got):\n%s", diff)
			}
		})
	}
}

func TestSummarizeCallStack(t *testing.T) {
	topPkgs := map[string]bool{"t1": true, "t2": true}
	vulnPkg := "v"

	for _, test := range []struct {
		in, want string
	}{
		{"a.F", ""},
		{"t1.F", ""},
		{"v.V", ""},
		{
			"t1.F v.V",
			"t1.F calls v.V",
		},
		{
			"t1.F t2.G v.V1 v.v2",
			"t2.G calls v.V1",
		},
		{
			"t1.F t2.G v.V$1 v.V1",
			"t2.G calls v.V, which eventually calls v.V1",
		},
		{
			"t1.F t2.G$1 v.V1",
			"t1.F calls t2.G, which eventually calls v.V1",
		},
		{
			"t1.F t2.G$1 v.V$1 v.V1",
			"t1.F calls t2.G, which eventually calls v.V1",
		},
		{
			"t1.F x.Y t2.G a.H b.I c.J v.V",
			"t2.G calls a.H, which eventually calls v.V",
		},
		{
			"t1.F x.Y t2.G a.H b.I c.J v.V$1 v.V1",
			"t2.G calls a.H, which eventually calls v.V1",
		},
	} {
		in := stringToCallStack(test.in)
		got := summarizeCallStack(in, topPkgs, vulnPkg)
		if got != test.want {
			t.Errorf("%s:\ngot  %s\nwant %s", test.in, got, test.want)
		}
	}
}

func stringToCallStack(s string) result.CallStack {
	var cs result.CallStack
	for _, e := range strings.Fields(s) {
		parts := strings.Split(e, ".")
		cs.Frames = append(cs.Frames, &result.StackFrame{
			PkgPath:  parts[0],
			FuncName: parts[1],
		})
	}
	return cs
}

// TestInits checks for correct positions of init functions
// and their respective calls (see #51575).
func TestInits(t *testing.T) {
	testClient := &test.MockClient{
		Ret: map[string][]*osv.Entry{
			"golang.org/amod": []*osv.Entry{
				{
					ID: "A", Affected: []osv.Affected{{Package: osv.Package{Name: "golang.org/amod"}, Ranges: osv.Affects{{Type: osv.TypeSemver}},
						EcosystemSpecific: osv.EcosystemSpecific{Imports: []osv.EcosystemSpecificImport{{
							Path: "golang.org/amod/avuln", Symbols: []string{"A"}},
						}},
					}},
				},
			},
			"golang.org/cmod": []*osv.Entry{
				{
					ID: "C", Affected: []osv.Affected{{Package: osv.Package{Name: "golang.org/cmod"}, Ranges: osv.Affects{{Type: osv.TypeSemver}},
						EcosystemSpecific: osv.EcosystemSpecific{Imports: []osv.EcosystemSpecificImport{{
							Path: "golang.org/cmod/cvuln", Symbols: []string{"C"}},
						}},
					}},
				},
			},
		},
	}
	e := packagestest.Export(t, packagestest.Modules, []packagestest.Module{
		{
			Name: "golang.org/entry",
			Files: map[string]interface{}{
				"x/x.go": `
			package x

			import (
				_ "golang.org/amod/avuln"
				_ "golang.org/bmod/b"
			)
			`,
			},
		},
		{
			Name: "golang.org/amod@v0.5.0",
			Files: map[string]interface{}{"avuln/avuln.go": `
			package avuln

			func init() {
				A()
			}

			func A() {}
			`},
		},
		{
			Name: "golang.org/bmod@v0.5.0",
			Files: map[string]interface{}{"b/b.go": `
			package b

			import _ "golang.org/cmod/cvuln"
			`},
		},
		{
			Name: "golang.org/cmod@v0.5.0",
			Files: map[string]interface{}{"cvuln/cvuln.go": `
			package cvuln

			var x int = C()

			func C() int {
				return 0
			}
			`},
		},
	})
	defer e.Cleanup()

	// Load x as entry package.
	pkgs, err := test.LoadPackages(e, path.Join(e.Temp(), "entry/x"))
	if err != nil {
		t.Fatal(err)
	}
	if len(pkgs) != 1 {
		t.Fatal("failed to load x test package")
	}
	vpkgs := vulncheck.Convert(pkgs)
	result, err := vulncheck.Source(context.Background(), vpkgs, &vulncheck.Config{Client: testClient})
	if err != nil {
		t.Fatal(err)
	}

	cs := vulncheck.CallStacks(result)
	updateInitPositions(cs, vpkgs)

	want := map[string][][]string{
		"A": [][]string{{
			// Entry init's position is the package statement.
			// It calls avuln.init at avuln import statement.
			"N:golang.org/entry/x.init	F:x.go:2:4	C:x.go:5:5",
			// implicit avuln.init is calls explicit init at the avuln
			// package statement.
			"N:golang.org/amod/avuln.init	F:avuln.go:2:4	C:avuln.go:2:4",
			"N:golang.org/amod/avuln.init#1	F:avuln.go:4:9	C:avuln.go:5:6",
			"N:golang.org/amod/avuln.A	F:avuln.go:8:9	C:",
		}},
		"C": [][]string{{
			"N:golang.org/entry/x.init	F:x.go:2:4	C:x.go:6:5",
			"N:golang.org/bmod/b.init	F:b.go:2:4	C:b.go:4:11",
			"N:golang.org/cmod/cvuln.init	F:cvuln.go:2:4	C:cvuln.go:4:17",
			"N:golang.org/cmod/cvuln.C	F:cvuln.go:6:9	C:",
		}},
	}
	if diff := cmp.Diff(want, strStacks(cs)); diff != "" {
		t.Errorf("modules mismatch (-want, +got):\n%s", diff)
	}
}

// strStacks creates a string representation of a call stacks map where
// vulnerability is represented with its ID and stack entry is a string
// "N:<package path.function name>  F:<function position> C:< call position>"
// File paths in positions consists of only file names.
func strStacks(callStacks map[*vulncheck.Vuln][]vulncheck.CallStack) map[string][][]string {
	m := make(map[string][][]string)
	for v, css := range callStacks {
		var scss [][]string
		for _, cs := range css {
			var scs []string
			for _, se := range cs {
				fPos := se.Function.Pos
				fp := fmt.Sprintf("%s:%d:%d", filepath.Base(fPos.Filename), fPos.Line, fPos.Column)

				var cp string
				if se.Call != nil && se.Call.Pos.IsValid() {
					cPos := se.Call.Pos
					cp = fmt.Sprintf("%s:%d:%d", filepath.Base(cPos.Filename), cPos.Line, cPos.Column)
				}

				sse := fmt.Sprintf("N:%s.%s\tF:%v\tC:%v", se.Function.PkgPath, se.Function.Name, fp, cp)
				scs = append(scs, sse)
			}
			scss = append(scss, scs)
		}
		m[v.OSV.ID] = scss
	}
	return m
}
