// Copyright 2019 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 postgres

import (
	"context"
	"database/sql"
	"errors"
	"sort"
	"strings"
	"testing"

	"github.com/google/go-cmp/cmp"
	"golang.org/x/pkgsite/internal/database"
	"golang.org/x/pkgsite/internal/derrors"
	"golang.org/x/pkgsite/internal/testing/sample"
	"golang.org/x/pkgsite/internal/version"
)

func TestDeleteModule(t *testing.T) {
	t.Parallel()
	testDB, release := acquire(t)
	defer release()
	ctx := context.Background()

	v := sample.DefaultModule()

	MustInsertModule(ctx, t, testDB, v)
	if _, err := testDB.GetModuleInfo(ctx, v.ModulePath, v.Version); err != nil {
		t.Fatal(err)
	}

	vm := sample.DefaultVersionMap()
	if err := testDB.UpsertVersionMap(ctx, vm); err != nil {
		t.Fatal(err)
	}
	if _, err := testDB.GetVersionMap(ctx, v.ModulePath, v.Version); err != nil {
		t.Fatal(err)
	}

	if err := testDB.DeleteModule(ctx, v.ModulePath, v.Version); err != nil {
		t.Fatal(err)
	}
	if _, err := testDB.GetModuleInfo(ctx, v.ModulePath, v.Version); !errors.Is(err, derrors.NotFound) {
		t.Errorf("got %v, want NotFound", err)
	}

	var x int
	err := testDB.Underlying().QueryRow(ctx, "SELECT 1 FROM imports_unique WHERE from_module_path = $1",
		v.ModulePath).Scan(&x)
	if err != sql.ErrNoRows {
		t.Errorf("imports_unique: got %v, want ErrNoRows", err)
	}
	err = testDB.Underlying().QueryRow(
		ctx,
		"SELECT 1 FROM version_map WHERE module_path = $1 AND resolved_version = $2",
		v.ModulePath, v.Version).Scan(&x)
	if err != sql.ErrNoRows {
		t.Errorf("version_map: got %v, want ErrNoRows", err)
	}
}

func TestDeleteFromSearch(t *testing.T) {
	t.Parallel()
	ctx := context.Background()

	const modulePath = "deleteme.com"

	initial := []searchDocumentRow{
		{modulePath + "/p1", modulePath, "v0.0.9", 0}, // oldest version of same module
		{modulePath + "/p2", modulePath, "v1.1.0", 0}, // older version of same module
		{modulePath + "/p4", modulePath, "v1.9.0", 0}, // newer version of same module
		{"other.org/p2", "other.org", "v1.1.0", 0},    // older version of a different module
	}

	insertInitial := func(db *DB) {
		t.Helper()
		for _, r := range initial {
			sm := sample.Module(r.ModulePath, r.Version, strings.TrimPrefix(r.PackagePath, r.ModulePath+"/"))
			MustInsertModule(ctx, t, db, sm)
		}
		// Older versions are deleted by InsertModule, so only the newest versions are here.
		checkSearchDocuments(ctx, t, db, initial[2:])
	}

	t.Run("deleteModuleFromSearchDocuments", func(t *testing.T) {
		// Non-empty list of packages tested above. This tests an empty list.
		testDB, release := acquire(t)
		defer release()
		insertInitial(testDB)

		if err := deleteModuleFromSearchDocuments(ctx, testDB.db, modulePath); err != nil {
			t.Fatal(err)
		}
		checkSearchDocuments(ctx, t, testDB, []searchDocumentRow{
			{"other.org/p2", "other.org", "v1.1.0", 0}, // other module not deleted
		})
	})
	t.Run("deleteOtherModulePackagesFromSearchDocuments", func(t *testing.T) {
		testDB, release := acquire(t)
		defer release()

		// Insert a module with two packages.
		m0 := sample.Module(modulePath, "v1.0.0", "p1", "p2")
		MustInsertModule(ctx, t, testDB, m0)
		// Set the imported-by count to a non-zero value so we can tell which
		// rows were deleted.
		if _, err := testDB.db.Exec(ctx, `UPDATE search_documents SET imported_by_count = 1`); err != nil {
			t.Fatal(err)
		}
		// Later version of module does not have p1.
		m1 := sample.Module(modulePath, "v1.1.0", "p2", "p3")
		MustInsertModule(ctx, t, testDB, m1)

		// p1 should be gone, p2 should be there with the same
		// imported_by_count, and p3 should be there with a zero count.
		want := []searchDocumentRow{
			{modulePath + "/p2", modulePath, "v1.1.0", 1},
			{modulePath + "/p3", modulePath, "v1.1.0", 0},
		}
		checkSearchDocuments(ctx, t, testDB, want)
	})
}

type searchDocumentRow struct {
	PackagePath, ModulePath, Version string
	ImportedByCount                  int
}

func readSearchDocuments(ctx context.Context, db *DB) ([]searchDocumentRow, error) {
	rows, err := database.CollectStructs[searchDocumentRow](ctx, db.db, `SELECT package_path, module_path, version, imported_by_count FROM search_documents`)
	if err != nil {
		return nil, err
	}
	return rows, err
}

func checkSearchDocuments(ctx context.Context, t *testing.T, db *DB, want []searchDocumentRow) {
	t.Helper()
	got, err := readSearchDocuments(ctx, db)
	if err != nil {
		t.Fatal(err)
	}
	less := func(r1, r2 searchDocumentRow) bool {
		if r1.PackagePath != r2.PackagePath {
			return r1.PackagePath < r2.PackagePath
		}
		if r1.ModulePath != r2.ModulePath {
			return r1.ModulePath < r2.ModulePath
		}
		return r1.Version < r2.Version
	}
	sort.Slice(got, func(i, j int) bool { return less(got[i], got[j]) })
	sort.Slice(want, func(i, j int) bool { return less(want[i], want[j]) })
	if diff := cmp.Diff(want, got); diff != "" {
		t.Errorf("search documents mismatch (-want, +got):\n%s", diff)
	}
}

func TestDeletePseudoversionsExcept(t *testing.T) {
	t.Parallel()
	ctx := context.Background()
	testDB, release := acquire(t)
	defer release()

	pseudo1 := "v0.0.0-20190904010203-89fb59e2e920"
	versions := []string{
		sample.VersionString,
		pseudo1,
		"v0.0.0-20190904010203-89fb59e2e920",
		"v0.0.0-20190904010203-89fb59e2e920",
	}
	for _, v := range versions {
		MustInsertModule(ctx, t, testDB, sample.Module(sample.ModulePath, v, ""))
	}
	if err := testDB.DeletePseudoversionsExcept(ctx, sample.ModulePath, pseudo1); err != nil {
		t.Fatal(err)
	}
	mods, err := getPathVersions(ctx, testDB, sample.ModulePath, version.TypeRelease)
	if err != nil {
		t.Fatal(err)
	}
	if len(mods) != 1 && mods[0].Version != sample.VersionString {
		t.Errorf("module version %q was not found", sample.VersionString)
	}
	mods, err = getPathVersions(ctx, testDB, sample.ModulePath, version.TypePseudo)
	if err != nil {
		t.Fatal(err)
	}
	if len(mods) != 1 {
		t.Fatalf("pseudoversions expected to be deleted were not")
	}
	if mods[0].Version != pseudo1 {
		t.Errorf("got %q; want %q", mods[0].Version, pseudo1)
	}
}
