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

import (
	"context"
	"flag"
	"fmt"
	"io/fs"
	"os"
	"path/filepath"
	"testing"

	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
	"golang.org/x/exp/maps"
	"golang.org/x/exp/slices"
	"golang.org/x/tools/txtar"
	"golang.org/x/vulndb/internal/cvelistrepo"
	"golang.org/x/vulndb/internal/cveschema"
	"golang.org/x/vulndb/internal/cveschema5"
	"golang.org/x/vulndb/internal/gitrepo"
	"golang.org/x/vulndb/internal/proxy"
	"golang.org/x/vulndb/internal/test"
	"gopkg.in/yaml.v3"
)

var (
	updateGolden     = flag.Bool("update", false, "update golden files")
	updateTxtarRepos = flag.Bool("update-repo", false, "update the test repos ({v4,v5}.txtar) with real CVE data - this takes a while")
)

var (
	testdata = filepath.Join("testdata", "cve")
	v4txtar  = filepath.Join(testdata, "v4.txtar")
	v5txtar  = filepath.Join(testdata, "v5.txtar")
	testCVEs = map[string]string{
		// First-party CVEs not assigned by the Go CNA.
		// (These were created before Go was a CNA).
		"CVE-2020-9283":  "golang.org/x/crypto",
		"CVE-2021-27919": "archive/zip",
		"CVE-2021-3115":  "cmd/go",

		// Third party CVEs, assigned by other CNAs.
		"CVE-2022-39213": "github.com/pandatix/go-cvss",
		"CVE-2023-44378": "github.com/Consensys/gnark",
		"CVE-2023-45141": "github.com/gofiber/fiber",

		// First-party CVEs, assigned by the Go CNA.
		"CVE-2023-29407": "golang.org/x/image",
		"CVE-2023-45283": "path/filepath",
		"CVE-2023-45285": "cmd/go",

		// A third-party CVE assigned by the Go CNA.
		"CVE-2023-45286": "github.com/go-resty/resty/v2",
	}
)

func TestMain(m *testing.M) {
	flag.Parse()
	if *updateTxtarRepos {
		ctx := context.Background()
		ids := maps.Keys(testCVEs)
		slices.Sort(ids)
		if err := cvelistrepo.WriteTxtarRepo(ctx, cvelistrepo.URLv4, v4txtar, ids); err != nil {
			fail(err)
		}
		if err := cvelistrepo.WriteTxtarRepo(ctx, cvelistrepo.URLv5, v5txtar, ids); err != nil {
			fail(err)
		}
	}
	os.Exit(m.Run())
}

func fail(err error) {
	fmt.Fprintln(os.Stderr, err)
	os.Exit(1)
}

const placeholderID = "PLACEHOLDER-ID"

func TestCVEToReport(t *testing.T) {
	pc, err := proxy.NewTestClient(t, *realProxy)
	if err != nil {
		t.Fatal(err)
	}

	newV4 := func() cvelistrepo.CVE {
		return new(cveschema.CVE)
	}
	toReportV4 := func(cve cvelistrepo.CVE, modulePath string) *Report {
		return New(ToCVE4(cve.(*cveschema.CVE)), placeholderID, modulePath, pc)
	}
	if err := run(t, v4txtar, newV4, toReportV4); err != nil {
		t.Fatal(err)
	}
}

func TestCVE5ToReport(t *testing.T) {
	pc, err := proxy.NewTestClient(t, *realProxy)
	if err != nil {
		t.Fatal(err)
	}

	newV5 := func() cvelistrepo.CVE {
		return new(cveschema5.CVERecord)
	}
	toReportV5 := func(cve cvelistrepo.CVE, modulePath string) *Report {
		return New(ToCVE5(cve.(*cveschema5.CVERecord)), placeholderID, modulePath, pc)
	}
	if err := run(t, v5txtar, newV5, toReportV5); err != nil {
		t.Fatal(err)
	}
}

func TestV4V5Equivalence(t *testing.T) {
	// Skip, but leave the test in case it is needed in the course of
	// the transition.
	// TODO(tatianabradley): Delete this test once we have completed the
	// transition to V5.
	t.Skip("V4 and V5 are no longer required to be equivalent.")
	if err := filepath.WalkDir(filepath.Join(testdata, "TestCVE5ToReport"), func(path string, d fs.DirEntry, err error) error {
		if err != nil {
			return err
		}
		if d.IsDir() {
			return nil
		}

		fname := filepath.Base(path)
		t.Run(fname, func(t *testing.T) {
			v5f, v5report, err := findCVEFile(path)
			if err != nil {
				t.Fatal(err)
			}
			v4file := filepath.Join(testdata, "TestCVEToReport", fname)
			v4f, v4report, err := findCVEFile(v4file)
			if err != nil {
				t.Fatal(err)
			}
			if v5f != v4f {
				t.Errorf("archive filename mismatch: v4=%s, v5=%s", v4f, v5f)
			}
			if diff := cmp.Diff(v4report, v5report,
				// Ignore credits and summary because these are not handled properly in v4.
				cmpopts.IgnoreFields(Report{}, "Credits", "Summary")); diff != "" {
				t.Errorf("mismatch (-v4, +v5):\n%s", diff)
			}
		})
		return nil
	}); err != nil {
		t.Fatal(err)
	}
}

func findCVEFile(tf string) (string, *Report, error) {
	ar, err := txtar.ParseFile(tf)
	if err != nil {
		return "", nil, err
	}
	for _, af := range ar.Files {
		if cveschema5.IsCVE(af.Name) {
			var r Report
			if err := yaml.Unmarshal(af.Data, &r); err != nil {
				return "", nil, err
			}
			return af.Name, &r, nil
		}
	}
	return "", nil, fmt.Errorf("%s: cve archive file not found", tf)
}

func run(t *testing.T, txtarFile string, newCVE func() cvelistrepo.CVE, toReport func(cvelistrepo.CVE, string) *Report) error {
	if *updateGolden {
		if err := os.RemoveAll(filepath.Join(testdata, t.Name())); err != nil {
			t.Fatal(err)
		}
	}

	repo, commit, err := gitrepo.TxtarRepoAndHead(txtarFile)
	if err != nil {
		return err
	}
	files, err := cvelistrepo.Files(repo, commit)
	if err != nil {
		return err
	}

	for _, file := range files {
		id := cveschema5.FindCVE(file.Filename)
		t.Run(id, func(t *testing.T) {
			cve := newCVE()
			if err := cvelistrepo.Parse(repo, file, cve); err != nil {
				t.Fatalf("Parse(%s)=%s", id, err)
			}

			mp, ok := testCVEs[id]
			if !ok {
				t.Fatalf("%s not found in testCVEs", id)
			}

			b, err := yaml.Marshal(toReport(cve, mp))
			if err != nil {
				t.Fatal(err)
			}

			tf := filepath.Join(testdata, t.Name()+".txtar")

			if *updateGolden {
				if err := test.WriteTxtar(tf, []txtar.File{
					{
						Name: id,
						Data: b,
					},
				}, fmt.Sprintf("Expected output of %s.", t.Name())); err != nil {
					t.Fatal(err)
				}
			}

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

			for _, af := range ar.Files {
				if af.Name != id {
					t.Errorf("unexpected archive file %s", af.Name)
					continue
				}
				want, got := string(b), string(af.Data)
				if diff := cmp.Diff(want, got); diff != "" {
					t.Errorf("%s content mismatch (-want, +got):\n%s", af.Name, diff)
				}
			}
		})
	}

	return nil
}
