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

import (
	"context"
	"errors"
	"testing"
	"time"

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

const testTimeout = 5 * time.Second

var testModule = &Module{
	ModulePath: sample.ModulePath,
	Version:    sample.VersionString,
	Files: map[string]string{
		"go.mod":      "module github.com/my/module\n\ngo 1.12",
		"LICENSE":     testhelper.BSD0License,
		"README.md":   "README FILE FOR TESTING.",
		"bar/LICENSE": testhelper.MITLicense,
		"bar/bar.go": `
						// package bar
						package bar

						// Bar returns the string "bar".
						func Bar() string {
							return "bar"
						}`,
		"foo/LICENSE.md": testhelper.MITLicense,
		"foo/foo.go": `
						// package foo
						package foo

						import (
							"fmt"

							"github.com/my/module/bar"
						)

						// FooBar returns the string "foo bar".
						func FooBar() string {
							return fmt.Sprintf("foo %s", bar.Bar())
						}`,
	},
}

func TestGetLatestInfo(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), testTimeout)
	defer cancel()

	testModules := []*Module{
		{
			ModulePath: sample.ModulePath,
			Version:    "v1.1.0",
			Files:      map[string]string{"bar.go": "package bar\nconst Version = 1.1"},
		},
		{
			ModulePath: sample.ModulePath,
			Version:    "v1.2.0",
			Files:      map[string]string{"bar.go": "package bar\nconst Version = 1.2"},
		},
	}
	client, teardownProxy := SetupTestProxy(t, testModules)
	defer teardownProxy()

	info, err := client.GetInfo(ctx, sample.ModulePath, internal.LatestVersion)
	if err != nil {
		t.Fatal(err)
	}

	if got, want := info.Version, "v1.2.0"; got != want {
		t.Errorf("GetInfo(ctx, %q, %q): Version = %q, want %q", sample.ModulePath, internal.LatestVersion, got, want)
	}
}

func TestListVersions(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), testTimeout)
	defer cancel()

	testModules := []*Module{
		{
			ModulePath: sample.ModulePath,
			Version:    "v1.1.0",
			Files:      map[string]string{"bar.go": "package bar\nconst Version = 1.1"},
		},
		{
			ModulePath: sample.ModulePath,
			Version:    "v1.2.0",
			Files:      map[string]string{"bar.go": "package bar\nconst Version = 1.2"},
		},
		{
			ModulePath: sample.ModulePath + "/bar",
			Version:    "v1.3.0",
			Files:      map[string]string{"bar.go": "package bar\nconst Version = 1.3"},
		},
	}
	client, teardownProxy := SetupTestProxy(t, testModules)
	defer teardownProxy()

	want := []string{"v1.1.0", "v1.2.0"}
	got, err := client.ListVersions(ctx, sample.ModulePath)
	if err != nil {
		t.Fatal(err)
	}
	if diff := cmp.Diff(want, got); diff != "" {
		t.Errorf("ListVersions(%q) diff:\n%s", sample.ModulePath, diff)
	}
}

func TestGetInfo(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), testTimeout)
	defer cancel()

	client, teardownProxy := SetupTestProxy(t, []*Module{testModule})
	defer teardownProxy()

	info, err := client.GetInfo(ctx, sample.ModulePath, sample.VersionString)
	if err != nil {
		t.Fatal(err)
	}

	if info.Version != sample.VersionString {
		t.Errorf("VersionInfo.Version for GetInfo(ctx, %q, %q) = %q, want %q",
			sample.ModulePath, sample.VersionString, info.Version, sample.VersionString)
	}
	expectedTime := time.Date(2019, 1, 30, 0, 0, 0, 0, time.UTC)
	if info.Time != expectedTime {
		t.Errorf("VersionInfo.Time for GetInfo(ctx, %q, %q) = %v, want %v", sample.ModulePath, sample.VersionString, info.Time, expectedTime)
	}
}

func TestGetInfoVersionDoesNotExist(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), testTimeout)
	defer cancel()

	client, teardownProxy := SetupTestProxy(t, []*Module{})
	defer teardownProxy()

	info, _ := client.GetInfo(ctx, sample.ModulePath, sample.VersionString)
	if info != nil {
		t.Errorf("GetInfo(ctx, %q, %q) = %v, want %v", sample.ModulePath, sample.VersionString, info, nil)
	}
}

func TestGetMod(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), testTimeout)
	defer cancel()

	client, teardownProxy := SetupTestProxy(t, []*Module{testModule})
	defer teardownProxy()

	bytes, err := client.GetMod(ctx, sample.ModulePath, sample.VersionString)
	if err != nil {
		t.Fatal(err)
	}
	got := string(bytes)
	want := "module github.com/my/module\n\ngo 1.12"
	if got != want {
		t.Errorf("got %q, want %q", got, want)
	}
}

func TestGetZip(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), testTimeout)
	defer cancel()

	client, teardownProxy := SetupTestProxy(t, []*Module{testModule})
	defer teardownProxy()

	zipReader, err := client.GetZip(ctx, sample.ModulePath, sample.VersionString)
	if err != nil {
		t.Fatal(err)
	}

	wantFiles := []string{
		sample.ModulePath + "@" + sample.VersionString + "/LICENSE",
		sample.ModulePath + "@" + sample.VersionString + "/README.md",
		sample.ModulePath + "@" + sample.VersionString + "/go.mod",
		sample.ModulePath + "@" + sample.VersionString + "/foo/foo.go",
		sample.ModulePath + "@" + sample.VersionString + "/foo/LICENSE.md",
		sample.ModulePath + "@" + sample.VersionString + "/bar/bar.go",
		sample.ModulePath + "@" + sample.VersionString + "/bar/LICENSE",
	}
	if len(zipReader.File) != len(wantFiles) {
		t.Errorf("GetZip(ctx, %q, %q) returned number of files: got %d, want %d",
			sample.ModulePath, sample.VersionString, len(zipReader.File), len(wantFiles))
	}

	expectedFileSet := map[string]bool{}
	for _, ef := range wantFiles {
		expectedFileSet[ef] = true
	}
	for _, zipFile := range zipReader.File {
		if !expectedFileSet[zipFile.Name] {
			t.Errorf("GetZip(ctx, %q, %q) returned unexpected file: %q", sample.ModulePath,
				sample.VersionString, zipFile.Name)
		}
		expectedFileSet[zipFile.Name] = false
	}
}

func TestGetZipNonExist(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), testTimeout)
	defer cancel()

	client, teardownProxy := SetupTestProxy(t, nil)
	defer teardownProxy()

	if _, err := client.GetZip(ctx, sample.ModulePath, sample.VersionString); !errors.Is(err, derrors.NotFound) {
		t.Errorf("got %v, want %v", err, derrors.NotFound)
	}
}

func TestEncodedURL(t *testing.T) {
	c := &Client{url: "u"}
	for _, test := range []struct {
		path, version, suffix string
		want                  string // empty => error
	}{
		{
			"mod.com", "v1.0.0", "info",
			"u/mod.com/@v/v1.0.0.info",
		},
		{
			"mod", "v1.0.0", "info",
			"", // bad module path
		},
		{
			"mod.com", "v1.0.0-rc1", "info",
			"u/mod.com/@v/v1.0.0-rc1.info",
		},
		{
			"mod.com/Foo", "v1.0.0-RC1", "info",
			"u/mod.com/!foo/@v/v1.0.0-!r!c1.info",
		},
		{
			"mod.com", ".", "info",
			"", // bad version
		},
		{
			"mod.com", "v1.0.0", "zip",
			"u/mod.com/@v/v1.0.0.zip",
		},
		{
			"mod", "v1.0.0", "zip",
			"", // bad module path
		},
		{
			"mod.com", "v1.0.0-rc1", "zip",
			"u/mod.com/@v/v1.0.0-rc1.zip",
		},
		{
			"mod.com/Foo", "v1.0.0-RC1", "zip",
			"u/mod.com/!foo/@v/v1.0.0-!r!c1.zip",
		},
		{
			"mod.com", ".", "zip",
			"", // bad version
		},
		{
			"mod.com", internal.LatestVersion, "info",
			"u/mod.com/@latest",
		},
		{
			"mod.com", internal.LatestVersion, "zip",
			"", // can't ask for latest zip
		},
		{
			"mod.com", "v1.0.0", "other",
			"", // only "info" or "zip"
		},
	} {
		got, err := c.escapedURL(test.path, test.version, test.suffix)
		if got != test.want || (err != nil) != (test.want == "") {
			t.Errorf("%s, %s, %s: got (%q, %v), want %q", test.path, test.version, test.suffix, got, err, test.want)
		}
	}
}
