// Copyright 2025 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 main

import (
	"bytes"
	"context"
	"strings"
	"testing"
	"time"

	"golang.org/x/pkgsite-metrics/internal/analysis"
	"golang.org/x/pkgsite-metrics/internal/bigquery"
	"google.golang.org/api/iterator"

	bq "cloud.google.com/go/bigquery"
)

type mockRowIterator struct {
	results []*analysis.Result
	index   int
}

func (it *mockRowIterator) Next(v interface{}) error {
	if it.index >= len(it.results) {
		return iterator.Done
	}
	res := it.results[it.index]
	val := v.(*analysis.Result)
	*val = *res
	it.index++
	return nil
}

type mockBQClient struct {
	expectedResults []*analysis.Result
}

func (c *mockBQClient) QueryWithParams(ctx context.Context, query string, params []bq.QueryParameter) (bigquery.RowIterator, error) {
	return &mockRowIterator{results: c.expectedResults}, nil
}

func (c *mockBQClient) FullTableName(tableID string) string { return "mock.table" }
func (c *mockBQClient) Close() error                        { return nil }

func TestFetchAndPrintResults(t *testing.T) {
	mockClient := &mockBQClient{
		expectedResults: []*analysis.Result{
			{
				ModulePath: "example.com/one",
				Version:    "v1.0.0",
				CreatedAt:  time.Now(),
				Diagnostics: []*analysis.Diagnostic{
					{
						PackageID:    "example.com/one [example.com/one.test]",
						AnalyzerName: "fuzzdetect",
						Category:     "",
						Position:     "https://go-mod-viewer.appspot.com/example.com@v1.0.0/one/quorum_test.go#L59",
						Message:      "found the use of fuzzing",
						Source:       bq.NullString{StringVal: "\nfunc FuzzCalculateQuorum(f *testing.F) {\n\t// Add examples to our fuzz corpus", Valid: true},
					},
				},
			},
		},
	}
	var out bytes.Buffer
	var lastCreatedAt time.Time
	processedIDs := make(map[string]struct{})

	count, err := fetchAndPrintResults(context.Background(), &out, mockClient, "fake-job-id", lastCreatedAt, processedIDs)
	if err != nil {
		t.Fatalf("fetchAndPrintResults failed: %v", err)
	}

	if count != len(mockClient.expectedResults) {
		t.Errorf("expected to process %d new results, but got %d", len(mockClient.expectedResults), count)
	}
	got := out.String()
	for _, result := range mockClient.expectedResults {
		if !strings.Contains(got, result.ModulePath) {
			t.Errorf("output did not contain first result; got:\n%s, wanted:%s", got, result.ModulePath)
		}
		if !strings.Contains(got, result.Version) {
			t.Errorf("output did not contain first result; got:\n%s, wanted:%s", got, result.Version)
		}
	}

	if len(processedIDs) != len(mockClient.expectedResults) {
		t.Errorf("expected %d processed IDs, but got %d", len(mockClient.expectedResults), len(processedIDs))
	}
}
