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

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

	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
	"golang.org/x/pkgsite-metrics/internal/analysis"
	"golang.org/x/pkgsite-metrics/internal/buildtest"
	"golang.org/x/pkgsite-metrics/internal/config"
	"golang.org/x/pkgsite-metrics/internal/proxy/proxytest"
	"golang.org/x/pkgsite-metrics/internal/queue"
	"golang.org/x/pkgsite-metrics/internal/scan"
)

func TestRunAnalysisBinary(t *testing.T) {
	mustMakeBinaryDir(t)
	binPath, cleanup := buildtest.GoBuild(t, "testdata/analyzer", "")
	defer cleanup()

	got, err := runAnalysisBinary(nil, binPath, "-name Fact", "testdata/module")
	if err != nil {
		t.Fatal(err)
	}
	want := analysis.JSONTree{
		"test_module": map[string]analysis.DiagnosticsOrError{
			"findcall": analysis.DiagnosticsOrError{
				Diagnostics: []analysis.JSONDiagnostic{
					{
						Posn:    "a.go:7:17",
						Message: "call of Fact(...)",
						SuggestedFixes: []analysis.JSONSuggestedFix{
							{
								Message: "Add '_TEST_'",
								Edits: []analysis.JSONTextEdit{{
									Filename: "a.go",
									Start:    77,
									End:      77,
									New:      "_TEST_",
								}},
							},
						},
					},
				},
			},
		},
	}
	// To make the test portable, compare the basenames of file paths.
	// This will be called for all strings, but in this case only file paths contain slashes.
	comparePaths := func(s1, s2 string) bool {
		return filepath.Base(s1) == filepath.Base(s2)
	}

	if diff := cmp.Diff(want, got, cmp.Comparer(comparePaths)); diff != "" {
		t.Errorf("mismatch (-want, +got):\n%s", diff)
	}
}

func TestCreateAnalysisQueueTasks(t *testing.T) {
	mods := []scan.ModuleSpec{
		{Path: "a.com/a", Version: "v1.2.3", ImportedBy: 1},
		{Path: "b.com/b", Version: "v1.0.0", ImportedBy: 2},
	}
	got := createAnalysisQueueTasks(&analysis.EnqueueParams{
		Binary:   "bin",
		Args:     "args",
		Insecure: true,
		Suffix:   "suff",
	}, mods)
	want := []queue.Task{
		&analysis.ScanRequest{
			ModuleURLPath: scan.ModuleURLPath{Module: "a.com/a", Version: "v1.2.3"},
			ScanParams: analysis.ScanParams{Binary: "bin", Args: "args",
				ImportedBy: 1, Insecure: true},
		},
		&analysis.ScanRequest{
			ModuleURLPath: scan.ModuleURLPath{Module: "b.com/b", Version: "v1.0.0"},
			ScanParams: analysis.ScanParams{Binary: "bin", Args: "args",
				ImportedBy: 2, Insecure: true},
		},
	}
	if diff := cmp.Diff(want, got); diff != "" {
		t.Errorf("mismatch (-want +got):\n%s", diff)
	}
}

func TestAnalysisScan(t *testing.T) {
	const (
		modulePath = "a.com/m"
		version    = "v1.2.3"
	)
	mustMakeBinaryDir(t)
	binaryPath, cleanup := buildtest.GoBuild(t, "testdata/analyzer", "")
	defer cleanup()
	proxyClient, cleanup2 := proxytest.SetupTestClient(t, []*proxytest.Module{
		{
			ModulePath: modulePath,
			Version:    version,
			Files: map[string]string{
				"go.mod": `module ` + modulePath,
				"a.go": `
package p
func F()  { G() }
func G() {}
`},
		},
	})
	defer cleanup2()

	diff := func(want, got *analysis.Result) {
		t.Helper()
		d := cmp.Diff(want, got,
			cmpopts.IgnoreFields(analysis.Diagnostic{}, "Position"))
		if d != "" {
			t.Errorf("mismatch (-want, +got)\n%s", d)
		}
	}

	s := &analysisServer{
		Server: &Server{
			proxyClient: proxyClient,
			cfg: &config.Config{
				BinaryBucket: "unused",
			},
		},
	}
	req := &analysis.ScanRequest{
		ModuleURLPath: scan.ModuleURLPath{Module: modulePath, Version: version},
		ScanParams: analysis.ScanParams{
			Binary:   "analyzer",
			Args:     "-name G",
			Insecure: true,
		},
	}
	wv := analysis.WorkVersion{BinaryArgs: "-name G", BinaryVersion: "bv", SchemaVersion: "sv"}
	got := s.scan(context.Background(), req, binaryPath, wv)
	want := &analysis.Result{
		ModulePath:    modulePath,
		Version:       version,
		SortVersion:   "1,2,3~",
		CommitTime:    proxytest.CommitTime,
		BinaryName:    "analyzer",
		WorkVersion:   wv,
		Error:         "",
		ErrorCategory: "",
		Diagnostics: []*analysis.Diagnostic{
			{
				PackageID:    "a.com/m",
				AnalyzerName: "findcall",
				Message:      "call of G(...)",
			},
		},
	}
	diff(want, got)

	// Test that errors are put into the Result.
	req.Binary = "bad"
	got = s.scan(context.Background(), req, "yyy", wv)
	// Trim varying part of error.
	if i := strings.LastIndexByte(got.Error, ':'); i > 0 {
		got.Error = got.Error[i+2:]
	}
	want = &analysis.Result{
		ModulePath:    modulePath,
		Version:       version,
		SortVersion:   "1,2,3~",
		BinaryName:    "bad",
		WorkVersion:   wv,
		ErrorCategory: "MISC",
		Error:         "executable file not found in $PATH",
	}
	diff(want, got)
}

func mustMakeBinaryDir(t *testing.T) {
	if err := os.Mkdir(binaryDir, 0777); err != nil && !os.IsExist(err) {
		t.Fatal(err)
	}
}
