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

import (
	"context"
	"flag"
	"fmt"
	"sort"
	"testing"
	"time"

	bq "cloud.google.com/go/bigquery"
	"cloud.google.com/go/civil"
	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
	"golang.org/x/exp/slices"
	"golang.org/x/pkgsite-metrics/internal/version"
	"google.golang.org/api/iterator"
)

var integration = flag.Bool("integration", false, "test against actual service")

func TestIntegration(t *testing.T) {
	must := func(err error) {
		t.Helper()
		if err != nil {
			t.Fatal(err)
		}
	}

	if !*integration {
		t.Skip("missing -integration")
	}
	ctx := context.Background()
	const projectID = "go-ecosystem"

	// Create a new dataset ID to avoid problems with re-using existing tables.
	dsID := fmt.Sprintf("test_%s", time.Now().Format("20060102T030405"))
	t.Logf("using dataset %s", dsID)
	client, err := NewClientCreate(ctx, projectID, dsID)
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		must(client.dataset.Delete(ctx))
	}()

	if _, err := client.CreateOrUpdateTable(ctx, VulncheckTableName); err != nil {
		t.Fatal(err)
	}
	defer func() { must(client.Table(VulncheckTableName).Delete(ctx)) }()

	tm := time.Date(2022, 7, 21, 0, 0, 0, 0, time.UTC)
	row := &VulnResult{
		ModulePath:  "m",
		Version:     "v",
		SortVersion: "sv",
		ImportedBy:  10,
		VulncheckWorkVersion: VulncheckWorkVersion{
			WorkerVersion:      "1",
			SchemaVersion:      "s",
			VulnVersion:        "2",
			VulnDBLastModified: tm,
		},
	}

	t.Run("upload", func(t *testing.T) {
		must(client.Upload(ctx, VulncheckTableName, row))
		// Round, strip monotonic data and convert to UTC.
		// Discrepancies of a few microseconds have been seen, so round to seconds
		// just to be safe.
		row.CreatedAt = row.CreatedAt.Round(time.Second).UTC()
		gots, err := readTable[VulnResult](ctx, client.Table(VulncheckTableName), nil)
		if err != nil {
			t.Fatal(err)
		}
		if g, w := len(gots), 1; g != w {
			t.Fatalf("got %d, rows, wanted %d", g, w)
		}
		got := gots[0]
		got.CreatedAt = got.CreatedAt.Round(time.Second)
		if diff := cmp.Diff(row, got); diff != "" {
			t.Errorf("mismatch (-want, +got):\n%s", diff)
		}
	})
	t.Run("work versions", func(t *testing.T) {
		wv, err := ReadVulncheckWorkVersions(ctx, client)
		if err != nil {
			t.Fatal(err)
		}
		wgot := wv[[2]string{"m", "v"}]
		if wgot == nil {
			t.Fatal("got nil, wanted work version")
		}
		if want := &row.VulncheckWorkVersion; !wgot.Equal(want) {
			t.Errorf("got %+v, want %+v", wgot, want)
		}

		if got := wv[[2]string{"m", "v2"}]; got != nil {
			t.Errorf("got %v; want nil", got)
		}
	})

	t.Run("latest", func(t *testing.T) {
		latestTableID := VulncheckTableName + "-latest"
		addTable(latestTableID, tableSchema(VulncheckTableName))
		must(client.CreateTable(ctx, latestTableID))
		defer func() { must(client.Table(latestTableID).Delete(ctx)) }()

		var want []*VulnResult
		// Module "a": same work version, should get the latest module version.
		a1 := &VulnResult{
			ModulePath: "a",
			Version:    "v1.0.0",
			ScanMode:   "M1",
			VulncheckWorkVersion: VulncheckWorkVersion{
				WorkerVersion:      "1",
				SchemaVersion:      "s",
				VulnVersion:        "2",
				VulnDBLastModified: tm,
			},
		}
		a2 := *a1
		a2.Version = "v1.1.0"
		want = append(want, &a2)

		// Different scan mode: should get this one too.
		a3 := a2
		a3.ScanMode = "M2"
		want = append(want, &a3)

		// Module "b": same module version, should get the latest work version.
		b1 := &VulnResult{
			ModulePath: "b",
			Version:    "v1.0.0",
			VulncheckWorkVersion: VulncheckWorkVersion{
				WorkerVersion:      "1",
				SchemaVersion:      "s",
				VulnVersion:        "2",
				VulnDBLastModified: tm,
			},
		}
		b2 := *b1
		b2.WorkerVersion = "0"
		want = append(want, b1)

		vrs := []*VulnResult{
			a1, &a2, &a3,
			b1, &b2,
		}
		for _, vr := range vrs {
			vr.SortVersion = version.ForSorting(vr.Version)
		}
		must(UploadMany(ctx, client, latestTableID, vrs, 20))

		got, err := fetchVulncheckResults(ctx, client, latestTableID)
		if err != nil {
			t.Fatal(err)
		}
		sort.Slice(got, func(i, j int) bool { return got[i].ModulePath < got[j].ModulePath })
		if diff := cmp.Diff(want, got, cmpopts.IgnoreFields(VulnResult{}, "CreatedAt")); diff != "" {
			t.Errorf("mismatch (-want, +got):\n%s", diff)
		}

		// Test InsertVulncheckResults
		reportTableID := latestTableID + "-report"
		addTable(reportTableID, tableSchema(VulncheckTableName+"-report"))
		reportTable := client.dataset.Table(reportTableID)
		// Table is created by InsertVulncheckResults.
		defer func() { must(reportTable.Delete(ctx)) }()

		if err := insertVulncheckResults(ctx, client, reportTableID, got, civil.DateOf(time.Now()), false); err != nil {
			t.Fatal(err)
		}
		rgot, err := readTable[ReportVulnResult](ctx, reportTable, func() *ReportVulnResult {
			return &ReportVulnResult{VulnResult: &VulnResult{}}
		})
		if err != nil {
			t.Fatal(err)
		}
		wantDate := civil.DateOf(time.Now())
		for _, r := range rgot {
			if r.ReportDate != wantDate {
				t.Errorf("got %s, want %s", r.ReportDate, wantDate)
			}
			if d := time.Minute; time.Since(r.InsertedAt) > d {
				t.Errorf("inserted at %s, more than %s ago", r.InsertedAt, d)
			}
			// Sanity check for VulnResult.
			if r.ModulePath != "a" && r.ModulePath != "b" {
				t.Errorf("got %q, want 'a' or 'b'", r.ModulePath)
			}

		}

	})
	t.Run("request counts", func(t *testing.T) {
		date := func(y, m, d int) civil.Date {
			return civil.Date{Year: y, Month: time.Month(m), Day: d}
		}

		must(client.CreateTable(ctx, VulnDBRequestTableName))
		defer client.Table(VulnDBRequestTableName).Delete(ctx)
		counts := []*VulnDBRequestCount{
			{Date: date(2022, 10, 1), Count: 1},
			{Date: date(2022, 10, 3), Count: 3},
			{Date: date(2022, 10, 4), Count: 4},
		}
		for _, row := range counts {
			must(client.Upload(ctx, VulnDBRequestTableName, row))
		}
		// Insert duplicates with a later time; we expect to get these, not the originals.
		time.Sleep(50 * time.Millisecond)
		for _, row := range counts {
			row.Count++
			must(client.Upload(ctx, VulnDBRequestTableName, row))
		}

		got, err := readVulnDBRequestCounts(ctx, client)
		if err != nil {
			t.Fatal(err)
		}
		want := slices.Clone(counts)
		slices.SortFunc(want, func(c1, c2 *VulnDBRequestCount) bool { return c1.Date.After(c2.Date) })
		if diff := cmp.Diff(want, got, cmpopts.IgnoreFields(VulnDBRequestCount{}, "InsertedAt")); diff != "" {
			t.Errorf("mismatch (-want, +got):\n%s", diff)
		}
	})

}

func readTable[T any](ctx context.Context, table *bq.Table, newT func() *T) ([]*T, error) {
	var ts []*T
	if newT == nil {
		newT = func() *T { return new(T) }
	}
	iter := table.Read(ctx)
	for {
		tp := newT()
		err := iter.Next(tp)
		if err == iterator.Done {
			break
		}
		if err != nil {
			return nil, err
		}
		ts = append(ts, tp)
	}
	return ts, nil
}

func TestIsNotFoundError(t *testing.T) {
	if !*integration {
		t.Skip("missing -integration")
	}
	client, err := bq.NewClient(context.Background(), "go-ecosystem")
	if err != nil {
		t.Fatal(err)
	}
	dataset := client.Dataset("nope")
	_, err = dataset.Metadata(context.Background())
	if !isNotFoundError(err) {
		t.Errorf("got false, want true for %v", err)
	}
}
