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

import (
	"context"
	"errors"
	"fmt"
	"strings"
	"testing"
	"time"

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

func setup(t *testing.T) (context.Context, *DataSource, func()) {
	t.Helper()
	contents := map[string]string{
		"go.mod":     "module foo.com/bar",
		"LICENSE":    testhelper.MITLicense,
		"baz/baz.go": "//Package baz provides a helpful constant.\npackage baz\nimport \"net/http\"\nconst OK = http.StatusOK",
	}
	// nrContents is the same as contents, except the license is non-redistributable.
	nrContents := map[string]string{
		"go.mod":     "module foo.com/nr",
		"LICENSE":    "unknown",
		"baz/baz.go": "//Package baz provides a helpful constant.\npackage baz\nimport \"net/http\"\nconst OK = http.StatusOK",
	}

	testModules := []*proxy.Module{
		{
			ModulePath: "foo.com/bar",
			Version:    "v1.1.0",
			Files:      contents,
		},
		{
			ModulePath: "foo.com/bar",
			Version:    "v1.2.0",
			Files:      contents,
		},
		{
			ModulePath: "foo.com/nr",
			Version:    "v1.1.0",
			Files:      nrContents,
		},
	}
	client, teardownProxy := proxy.SetupTestClient(t, testModules)
	ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
	return ctx, New(client), func() {
		teardownProxy()
		cancel()
	}
}

var (
	wantLicenseMD  = sample.LicenseMetadata[0]
	wantLicense    = &licenses.License{Metadata: wantLicenseMD}
	wantLicenseMIT = &licenses.License{
		Metadata: &licenses.Metadata{
			Types:    []string{"MIT"},
			FilePath: "LICENSE",
			Coverage: licensecheck.Coverage{
				Percent: 100,
				Match:   []licensecheck.Match{{Name: "MIT", Type: licensecheck.MIT, Percent: 100, End: 1049}},
			},
		},
		Contents: []byte(testhelper.MITLicense),
	}
	wantLicenseBSD = &licenses.License{
		Metadata: &licenses.Metadata{
			Types:    []string{"BSD-0-Clause"},
			FilePath: "qux/LICENSE",
			Coverage: licensecheck.Coverage{
				Percent: 100,
				Match:   []licensecheck.Match{{Name: "BSD-0-Clause", Type: licensecheck.BSD, Percent: 100, End: 633}},
			},
		},
		Contents: []byte(testhelper.BSD0License),
	}
	wantPackage = internal.LegacyPackage{
		Path:              "foo.com/bar/baz",
		Name:              "baz",
		Imports:           []string{"net/http"},
		Synopsis:          "Package baz provides a helpful constant.",
		V1Path:            "foo.com/bar/baz",
		Licenses:          []*licenses.Metadata{wantLicenseMD},
		IsRedistributable: true,
		GOOS:              "linux",
		GOARCH:            "amd64",
	}
	wantModuleInfo = internal.ModuleInfo{
		ModulePath:        "foo.com/bar",
		Version:           "v1.2.0",
		CommitTime:        time.Date(2019, 1, 30, 0, 0, 0, 0, time.UTC),
		IsRedistributable: true,
		HasGoMod:          true,
	}
	wantVersionedPackage = &internal.LegacyVersionedPackage{
		LegacyModuleInfo: internal.LegacyModuleInfo{
			ModuleInfo: wantModuleInfo,
		},
		LegacyPackage: wantPackage,
	}
	cmpOpts = append([]cmp.Option{
		cmpopts.IgnoreFields(internal.LegacyPackage{}, "DocumentationHTML"),
		cmpopts.IgnoreFields(licenses.License{}, "Contents"),
	}, sample.LicenseCmpOpts...)
)

func TestDataSource_GetModuleInfo(t *testing.T) {
	ctx, ds, teardown := setup(t)
	defer teardown()
	got, err := ds.GetModuleInfo(ctx, "foo.com/bar", "v1.2.0")
	if err != nil {
		t.Fatal(err)
	}
	if diff := cmp.Diff(&wantModuleInfo, got, cmpOpts...); diff != "" {
		t.Errorf("GetModuleInfo diff (-want +got):\n%s", diff)
	}
}

func TestDataSource_GetUnitMeta(t *testing.T) {
	ctx, ds, teardown := setup(t)
	defer teardown()

	for _, test := range []struct {
		path, modulePath, version string
		want                      *internal.UnitMeta
	}{
		{
			path:       "foo.com/bar",
			modulePath: "foo.com/bar",
			version:    "v1.1.0",
			want: &internal.UnitMeta{
				ModulePath:        "foo.com/bar",
				Version:           "v1.1.0",
				IsRedistributable: true,
			},
		},
		{
			path:       "foo.com/bar/baz",
			modulePath: "foo.com/bar",
			version:    "v1.1.0",
			want: &internal.UnitMeta{
				ModulePath:        "foo.com/bar",
				Name:              "baz",
				Version:           "v1.1.0",
				IsRedistributable: true,
			},
		},
		{
			path:       "foo.com/bar/baz",
			modulePath: internal.UnknownModulePath,
			version:    "v1.1.0",
			want: &internal.UnitMeta{
				ModulePath:        "foo.com/bar",
				Name:              "baz",
				Version:           "v1.1.0",
				IsRedistributable: true,
			},
		},
		{
			path:       "foo.com/bar/baz",
			modulePath: internal.UnknownModulePath,
			version:    internal.LatestVersion,
			want: &internal.UnitMeta{
				ModulePath:        "foo.com/bar",
				Name:              "baz",
				Version:           "v1.2.0",
				IsRedistributable: true,
			},
		},
	} {
		t.Run(test.path, func(t *testing.T) {
			got, err := ds.GetUnitMeta(ctx, test.path, test.modulePath, test.version)
			if err != nil {
				t.Fatal(err)
			}
			test.want.Path = test.path
			if diff := cmp.Diff(got, test.want); diff != "" {
				t.Errorf("mismatch (-want +got):\n%s", diff)
			}
		})
	}
}

func TestDataSource_Bypass(t *testing.T) {
	for _, bypass := range []bool{false, true} {
		t.Run(fmt.Sprintf("bypass=%t", bypass), func(t *testing.T) {
			// re-create the data source to get around caching
			ctx, ds, teardown := setup(t)
			defer teardown()
			ds.bypassLicenseCheck = bypass
			for _, mpath := range []string{"foo.com/bar", "foo.com/nr"} {
				wantEmpty := !bypass && strings.HasSuffix(mpath, "/nr")

				got, err := ds.getModule(ctx, mpath, "v1.1.0")
				if err != nil {
					t.Fatal(err)
				}
				// Assume internal.Module.RemoveNonRedistributableData is correct; we just
				// need to check one value to confirm that it was called.
				if gotEmpty := (got.Licenses[0].Contents == nil); gotEmpty != wantEmpty {
					t.Errorf("bypass %t for %q: got empty %t, want %t", bypass, mpath, gotEmpty, wantEmpty)
				}
			}
		})
	}
}

func TestDataSource_GetLatestMajorVersion(t *testing.T) {
	t.Helper()
	testModules := []*proxy.Module{
		{
			ModulePath: "foo.com/bar",
		},
		{
			ModulePath: "foo.com/bar/v2",
		},
		{
			ModulePath: "foo.com/bar/v3",
		},
		{
			ModulePath: "bar.com/foo",
		},
	}
	client, teardownProxy := proxy.SetupTestClient(t, testModules)
	defer teardownProxy()
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	ds := New(client)

	for _, test := range []struct {
		seriesPath  string
		wantVersion string
		wantErr     error
	}{
		{
			seriesPath:  "foo.com/bar",
			wantVersion: "/v3",
		},
		{
			seriesPath:  "bar.com/foo",
			wantVersion: "",
		},
		{
			seriesPath: "boo.com/far",
			wantErr:    derrors.NotFound,
		},
	} {
		gotVersion, err := ds.GetLatestMajorVersion(ctx, test.seriesPath)
		if err != nil {
			if test.wantErr == nil {
				t.Fatalf("got unexpected error %v", err)
			}
			if !errors.Is(err, test.wantErr) {
				t.Errorf("got err = %v, want Is(%v)", err, test.wantErr)
			}
		}
		if gotVersion != test.wantVersion {
			t.Errorf("GetLatestMajorVersion(%v) = %v, want %v", test.seriesPath, gotVersion, test.wantVersion)
		}
	}
}
