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

import (
	"context"
	"errors"
	"net/http"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
	"golang.org/x/pkgsite/internal"
	"golang.org/x/pkgsite/internal/derrors"
	"golang.org/x/pkgsite/internal/licenses"
	"golang.org/x/pkgsite/internal/postgres"
	"golang.org/x/pkgsite/internal/proxy/proxytest"
	"golang.org/x/pkgsite/internal/source"
	"golang.org/x/pkgsite/internal/testing/sample"
	"golang.org/x/pkgsite/internal/testing/testhelper"
)

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

	// This test checks that re-fetching a version will cause its data to be
	// overwritten.  This is achieved by fetching against two different versions
	// of the (fake) proxy, though in reality the most likely cause of changes to
	// a version is updates to our data model or fetch logic.
	defer postgres.ResetTestDB(testDB, t)

	var (
		modulePath = sample.ModulePath
		version    = sample.VersionString
		pkgFoo     = sample.ModulePath + "/foo"
		foo        = map[string]string{
			"foo/foo.go": "// Package foo\npackage foo\n\nconst Foo = 42",
			"README.md":  "This is a readme",
			"LICENSE":    testhelper.MITLicense,
		}
		pkgBar = sample.ModulePath + "/bar"
		foobar = map[string]string{
			"LICENSE":       testhelper.MITLicense,
			"bar/README.md": "This is a readme",
			"bar/bar.go":    "// Package bar\npackage bar\n\nconst Bar = 21",
			"foo/foo.go":    "// Package foo\npackage foo\n\nconst Foo = 42",
		}
	)

	// First fetch and insert a version containing package foo, and verify that
	// foo can be retrieved.
	proxyClient, teardownProxy := proxytest.SetupTestClient(t, []*proxytest.Module{
		{
			ModulePath: modulePath,
			Version:    version,
			Files:      foo,
		},
	})
	defer teardownProxy()
	sourceClient := source.NewClient(http.DefaultClient)
	f := &Fetcher{proxyClient, sourceClient, testDB, nil, nil, ""}
	if _, _, err := f.FetchAndUpdateState(ctx, sample.ModulePath, version, testAppVersion); err != nil {
		t.Fatalf("FetchAndUpdateState(%q, %q): %v", sample.ModulePath, version, err)
	}

	if _, err := testDB.GetUnitMeta(ctx, pkgFoo, internal.UnknownModulePath, version); err != nil {
		t.Error(err)
	}

	// Now re-fetch and verify that contents were overwritten.
	proxyClient, teardownProxy = proxytest.SetupTestClient(t, []*proxytest.Module{
		{
			ModulePath: sample.ModulePath,
			Version:    version,
			Files:      foobar,
		},
	})
	defer teardownProxy()

	f = &Fetcher{proxyClient, sourceClient, testDB, nil, nil, ""}
	if _, _, err := f.FetchAndUpdateState(ctx, sample.ModulePath, version, testAppVersion); err != nil {
		t.Fatalf("FetchAndUpdateState(%q, %q): %v", modulePath, version, err)
	}
	want := &internal.Unit{
		UnitMeta: internal.UnitMeta{
			ModuleInfo: internal.ModuleInfo{
				ModulePath:        sample.ModulePath,
				Version:           version,
				CommitTime:        time.Date(2019, 1, 30, 0, 0, 0, 0, time.UTC),
				IsRedistributable: true,
				SourceInfo:        source.NewGitHubInfo("https://"+sample.ModulePath, "", sample.VersionString),
				LatestVersion:     version,
			},
			Path: sample.ModulePath + "/bar",
			Name: "bar",
		},
		IsRedistributable: true,
		Licenses: []*licenses.Metadata{
			{Types: []string{"MIT"}, FilePath: "LICENSE"},
		},
		Readme: &internal.Readme{
			Filepath: "bar/README.md",
			Contents: "This is a readme",
		},
		Documentation: []*internal.Documentation{{
			Synopsis: "Package bar",
			GOOS:     "linux",
			GOARCH:   "amd64",
		}},
		Subdirectories: []*internal.PackageMeta{
			{
				Path:              "github.com/valid/module_name/bar",
				Name:              "bar",
				Synopsis:          "Package bar",
				IsRedistributable: true,
				Licenses:          sample.LicenseMetadata(),
			},
		},
		SymbolHistory: map[string]string{"Bar": "v1.0.0"},
	}
	got, err := testDB.GetUnitMeta(ctx, pkgBar, internal.UnknownModulePath, version)
	if err != nil {
		t.Fatal(err)
	}
	if diff := cmp.Diff(want.UnitMeta, *got,
		cmp.AllowUnexported(source.Info{}),
		cmpopts.IgnoreFields(licenses.Metadata{}, "Coverage"),
		cmpopts.IgnoreFields(internal.UnitMeta{}, "HasGoMod"),
	); diff != "" {
		t.Fatalf("testDB.GetUnitMeta(ctx, %q, %q) mismatch (-want +got):\n%s", want.ModulePath, want.Version, diff)
	}

	gotPkg, err := testDB.GetUnit(ctx, got, internal.WithMain|internal.WithDocsSource, internal.BuildContext{})
	if err != nil {
		t.Fatal(err)
	}
	if diff := cmp.Diff(want, gotPkg,
		cmp.AllowUnexported(source.Info{}),
		cmpopts.IgnoreFields(internal.Unit{}, "Documentation", "BuildContexts"),
		cmpopts.IgnoreFields(licenses.Metadata{}, "Coverage"),
		cmpopts.IgnoreFields(internal.UnitMeta{}, "HasGoMod"),
	); diff != "" {
		t.Errorf("mismatch on readme (-want +got):\n%s", diff)
	}
	if got, want := gotPkg.Documentation, want.Documentation; got == nil || want == nil {
		if !cmp.Equal(got, want) {
			t.Fatalf("mismatch on documentation: got: %v\nwant: %v", got, want)
		}
		return
	}

	// Now re-fetch and verify that contents were overwritten.
	proxyClient, teardownProxy = proxytest.SetupTestClient(t, []*proxytest.Module{
		{
			ModulePath: modulePath,
			Version:    version,
			Files:      foo,
		},
	})
	defer teardownProxy()
	f = &Fetcher{proxyClient, sourceClient, testDB, nil, nil, ""}
	if _, _, err := f.FetchAndUpdateState(ctx, modulePath, version, testAppVersion); !errors.Is(err, derrors.DBModuleInsertInvalid) {
		t.Fatalf("FetchAndUpdateState(%q, %q): %v", modulePath, version, err)
	}
}
