// Copyright 2021 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"
	"encoding/json"
	"strings"
	"testing"

	"github.com/go-git/go-git/v5"
	"github.com/go-git/go-git/v5/plumbing"
	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
	"golang.org/x/vuln/internal/cveschema"
	"golang.org/x/vuln/internal/worker/log"
	"golang.org/x/vuln/internal/worker/store"
)

func TestRepoCVEFiles(t *testing.T) {
	repo, err := readTxtarRepo("testdata/basic.txtar")
	if err != nil {
		t.Fatal(err)
	}
	h, err := headHash(repo)
	if err != nil {
		t.Fatal(err)
	}
	got, err := repoCVEFiles(repo, h)
	if err != nil {
		t.Fatal(err)
	}

	want := []repoFile{
		{dirpath: "2021/0xxx", filename: "CVE-2021-0001.json"},
		{dirpath: "2021/0xxx", filename: "CVE-2021-0010.json"},
		{dirpath: "2021/1xxx", filename: "CVE-2021-1384.json"},
	}

	if diff := cmp.Diff(want, got, cmp.AllowUnexported(repoFile{}), cmpopts.IgnoreFields(repoFile{}, "hash")); diff != "" {
		t.Errorf("mismatch (-want, +got):\n%s", diff)
	}
}

func TestDoUpdate(t *testing.T) {
	ctx := log.WithLineLogger(context.Background())
	repo, err := readTxtarRepo("testdata/basic.txtar")
	if err != nil {
		t.Fatal(err)
	}
	h, err := headHash(repo)
	if err != nil {
		t.Fatal(err)
	}
	needsIssue := func(cve *cveschema.CVE) (bool, error) {
		return strings.HasSuffix(cve.ID, "0001"), nil
	}

	ref, err := repo.Reference(plumbing.HEAD, true)
	if err != nil {
		t.Fatal(err)
	}
	commitHash := ref.Hash().String()
	const (
		path1 = "2021/0xxx/CVE-2021-0001.json"
		path2 = "2021/0xxx/CVE-2021-0010.json"
		path3 = "2021/1xxx/CVE-2021-1384.json"
	)
	cve1, bh1 := readCVE(t, repo, path1)
	cve2, bh2 := readCVE(t, repo, path2)
	cve3, bh3 := readCVE(t, repo, path3)

	// CVERecords after the above CVEs are added to an empty DB.
	rs := []*store.CVERecord{
		{
			ID:          cve1.ID,
			CVEState:    cve1.State,
			Path:        path1,
			BlobHash:    bh1,
			CommitHash:  commitHash,
			TriageState: store.TriageStateNeedsIssue, // a public CVE, needsIssue returns true
		},
		{
			ID:          cve2.ID,
			CVEState:    cve2.State,
			Path:        path2,
			BlobHash:    bh2,
			CommitHash:  commitHash,
			TriageState: store.TriageStateNoActionNeeded, // state is reserved
		},
		{
			ID:          cve3.ID,
			CVEState:    cve3.State,
			Path:        path3,
			BlobHash:    bh3,
			CommitHash:  commitHash,
			TriageState: store.TriageStateNoActionNeeded, // state is rejected
		},
	}

	// withTriageState returns a copy of r with the TriageState field changed to ts.
	withTriageState := func(r *store.CVERecord, ts store.TriageState) *store.CVERecord {
		c := *r
		c.BlobHash += "x" // if we don't use a different blob hash, no update will happen
		c.CommitHash = "?"
		c.TriageState = ts
		return &c
	}

	for _, test := range []struct {
		name string
		cur  []*store.CVERecord // current state of DB
		want []*store.CVERecord // expected state after update
	}{
		{
			name: "empty",
			cur:  nil,
			want: rs,
		},
		{
			name: "no change",
			cur:  rs,
			want: rs,
		},
		{
			name: "pre-issue changes",
			cur: []*store.CVERecord{
				// NoActionNeeded -> NeedsIssue
				withTriageState(rs[0], store.TriageStateNoActionNeeded),
				// NeedsIssue -> NoActionNeeded
				withTriageState(rs[1], store.TriageStateNeedsIssue),
				// NoActionNeeded, triage state stays the same but other fields change.
				withTriageState(rs[2], store.TriageStateNoActionNeeded),
			},
			want: rs,
		},
		{
			name: "post-issue changes",
			cur: []*store.CVERecord{
				// IssueCreated -> Updated
				withTriageState(rs[0], store.TriageStateIssueCreated),
				withTriageState(rs[1], store.TriageStateUpdatedSinceIssueCreation),
			},
			want: []*store.CVERecord{
				func() *store.CVERecord {
					c := *rs[0]
					c.TriageState = store.TriageStateUpdatedSinceIssueCreation
					c.TriageStateReason = "CVE changed; needs issue = true"
					return &c
				}(),
				func() *store.CVERecord {
					c := *rs[1]
					c.TriageState = store.TriageStateUpdatedSinceIssueCreation
					c.TriageStateReason = "CVE changed; needs issue = false"
					return &c
				}(),
				rs[2],
			},
		},
	} {
		t.Run(test.name, func(t *testing.T) {
			mstore := store.NewMemStore()
			createCVERecords(t, mstore, test.cur)
			if err := doUpdate(ctx, repo, h, mstore, needsIssue); err != nil {
				t.Fatal(err)
			}
			got := mstore.CVERecords()
			want := map[string]*store.CVERecord{}
			for _, cr := range test.want {
				want[cr.ID] = cr
			}
			if diff := cmp.Diff(want, got); diff != "" {
				t.Errorf("mismatch (-want, +got):\n%s", diff)
			}
		})
	}
}

func readCVE(t *testing.T, repo *git.Repository, path string) (*cveschema.CVE, string) {
	blob := findBlob(t, repo, path)
	var cve cveschema.CVE
	if err := json.Unmarshal(readBlob(t, blob), &cve); err != nil {
		t.Fatal(err)
	}
	return &cve, blob.Hash.String()
}

func createCVERecords(t *testing.T, s store.Store, crs []*store.CVERecord) {
	err := s.RunTransaction(context.Background(), func(_ context.Context, tx store.Transaction) error {
		for _, cr := range crs {
			if err := tx.CreateCVERecord(cr); err != nil {
				return err
			}
		}
		return nil
	})
	if err != nil {
		t.Fatal(err)
	}
}
