/* Copyright 2018 The Bazel Authors. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package repo

import (
	"errors"
	"os"
	"path/filepath"
	"testing"

	"golang.org/x/tools/go/vcs"
)

func TestRootSpecialCases(t *testing.T) {
	for _, tc := range []struct {
		in, wantRoot, wantName string
		repos                  []Repo
		wantError              bool
	}{
		{in: "golang.org/x/net/context", wantRoot: "golang.org/x/net", wantName: "org_golang_x_net"},
		{in: "golang.org/x/tools/go/vcs", wantRoot: "golang.org/x/tools", wantName: "org_golang_x_tools"},
		{in: "golang.org/x/goimports", wantRoot: "golang.org/x/goimports", wantName: "org_golang_x_goimports"},
		{in: "cloud.google.com/fashion/industry", wantRoot: "cloud.google.com/fashion", wantName: "com_google_cloud_fashion"},
		{in: "github.com/foo", wantError: true},
		{in: "github.com/foo/bar", wantRoot: "github.com/foo/bar", wantName: "com_github_foo_bar"},
		{in: "github.com/foo/bar/baz", wantRoot: "github.com/foo/bar", wantName: "com_github_foo_bar"},
		{in: "gopkg.in/yaml.v2", wantRoot: "gopkg.in/yaml.v2", wantName: "in_gopkg_yaml_v2"},
		{in: "gopkg.in/src-d/go-git.v4", wantRoot: "gopkg.in/src-d/go-git.v4", wantName: "in_gopkg_src_d_go_git_v4"},
		{in: "unsupported.org/x/net/context", wantError: true},
		{
			in: "private.com/my/repo/package/path",
			repos: []Repo{
				{
					Name:     "com_other_host_repo",
					GoPrefix: "other-host.com/repo",
				}, {
					Name:     "com_private_my_repo",
					GoPrefix: "private.com/my/repo",
				},
			},
			wantRoot: "private.com/my/repo",
			wantName: "com_private_my_repo",
		},
		{
			in: "unsupported.org/x/net/context",
			repos: []Repo{
				{
					Name:     "com_private_my_repo",
					GoPrefix: "private.com/my/repo",
				},
			},
			wantError: true,
		},
		{
			in: "github.com/foo/bar",
			repos: []Repo{{
				Name:     "custom_repo",
				GoPrefix: "github.com/foo/bar",
			}},
			wantRoot: "github.com/foo/bar",
			wantName: "custom_repo",
		},
	} {
		t.Run(tc.in, func(t *testing.T) {
			rc := NewStubRemoteCache(tc.repos)
			if gotRoot, gotName, err := rc.Root(tc.in); err != nil {
				if !tc.wantError {
					t.Errorf("unexpected error: %v", err)
				}
			} else if tc.wantError {
				t.Errorf("unexpected success: %v", tc.in)
			} else if gotRoot != tc.wantRoot {
				t.Errorf("root for %q: got %q; want %q", tc.in, gotRoot, tc.wantRoot)
			} else if gotName != tc.wantName {
				t.Errorf("name for %q: got %q; want %q", tc.in, gotName, tc.wantName)
			}
		})
	}
}

func TestRootStatic(t *testing.T) {
	for _, tc := range []struct {
		in, wantRoot, wantName string
		repos                  []Repo
	}{
		{
			in: "private.com/my/repo/package/path",
			repos: []Repo{
				{
					Name:     "com_other_host_repo",
					GoPrefix: "other-host.com/repo",
				}, {
					Name:     "com_private_my_repo",
					GoPrefix: "private.com/my/repo",
				},
			},
			wantRoot: "private.com/my/repo",
			wantName: "com_private_my_repo",
		},
		{
			in: "unsupported.org/x/net/context",
			repos: []Repo{
				{
					Name:     "com_private_my_repo",
					GoPrefix: "private.com/my/repo",
				},
			},
			wantRoot: "",
			wantName: "",
		},
	} {
		t.Run(tc.in, func(t *testing.T) {
			rc := NewStubRemoteCache(tc.repos)
			if gotRoot, gotName, err := rc.RootStatic(tc.in); err != nil {
				t.Errorf("unexpected error: %v", err)
			} else if gotRoot != tc.wantRoot {
				t.Errorf("root for %q: got %q; want %q", tc.in, gotRoot, tc.wantRoot)
			} else if gotName != tc.wantName {
				t.Errorf("name for %q: got %q; want %q", tc.in, gotName, tc.wantName)
			}
		})
	}
}

func TestRootPopulatedFromGoMod(t *testing.T) {
	tmpDir := t.TempDir()
	goModPath := filepath.Join(tmpDir, "go.mod")
	goModData := []byte(`
		module example.com/use
		go 1.19
		require example.com/good v1.0.0
	`)
	if err := os.WriteFile(goModPath, goModData, 0666); err != nil {
		t.Fatal(err)
	}

	rc := NewStubRemoteCache(nil)
	if err := rc.PopulateFromGoMod(goModPath); err != nil {
		t.Fatal(err)
	}
	errResolve := errors.New("test cannot lookup external package")
	rc.RepoRootForImportPath = func(string, bool) (*vcs.RepoRoot, error) {
		return nil, errResolve
	}

	// Resolving golang.org/x/mod/module from go.mod should work.
	goodPkgPath := "example.com/good/pkg"
	wantRoot := "example.com/good"
	wantName := "com_example_good"
	root, name, err := rc.Root(goodPkgPath)
	if err != nil {
		t.Fatalf("could not resolve %q from go.mod: %v", goodPkgPath, err)
	}
	if root != wantRoot {
		t.Errorf("got root %q; want %q", root, wantRoot)
	}
	if name != wantName {
		t.Errorf("got name %q; want %q", root, wantName)
	}

	// Resolving another module should fail because RepoRootForImportPath
	// is stubbed out.
	badPkgPath := "example.com/bad/pkg"
	if _, _, err := rc.Root(badPkgPath); err == nil {
		t.Errorf("resolving %q: unexpected success", badPkgPath)
	} else if !errors.Is(err, errResolve) {
		t.Errorf("resolving %q: got error %v, want %v", badPkgPath, err, errResolve)
	}
}

func TestRemote(t *testing.T) {
	for _, tc := range []struct {
		desc, root          string
		repos               []Repo
		wantRemote, wantVCS string
		wantError           bool
	}{
		{
			desc:      "unstubbed_remote",
			root:      "github.com/bazelbuild/bazel-gazelle",
			wantError: true, // stub should return an error
		}, {
			desc: "known_repo",
			root: "github.com/example/project",
			repos: []Repo{{
				Name:     "com_github_example_project",
				GoPrefix: "github.com/example/project",
				Remote:   "https://private.com/example/project",
				VCS:      "git",
			}},
			wantRemote: "https://private.com/example/project",
			wantVCS:    "git",
		}, {
			desc:       "git_repo",
			root:       "example.com/repo", // stub knows this
			wantRemote: "https://example.com/repo.git",
			wantVCS:    "git",
		}, {
			desc: "local_repo",
			root: "github.com/example/project",
			repos: []Repo{{
				Name:     "com_github_example_project",
				GoPrefix: "github.com/example/project",
				Remote:   "/home/joebob/go/src/github.com/example/project",
				VCS:      "local",
			}},
			wantRemote: "/home/joebob/go/src/github.com/example/project",
			wantVCS:    "local",
		},
	} {
		t.Run(tc.desc, func(t *testing.T) {
			rc := NewStubRemoteCache(tc.repos)
			if gotRemote, gotVCS, err := rc.Remote(tc.root); err != nil {
				if !tc.wantError {
					t.Errorf("unexpected error: %v", err)
				}
			} else if tc.wantError {
				t.Errorf("unexpected success")
			} else if gotRemote != tc.wantRemote {
				t.Errorf("remote for %q: got %q ; want %q", tc.root, gotRemote, tc.wantRemote)
			} else if gotVCS != tc.wantVCS {
				t.Errorf("vcs for %q: got %q ; want %q", tc.root, gotVCS, tc.wantVCS)
			}
		})
	}
}

func TestHead(t *testing.T) {
	for _, tc := range []struct {
		desc, remote, vcs   string
		wantCommit, wantTag string
		wantError           bool
	}{
		{
			desc:      "unstubbed_remote",
			remote:    "https://github.com/bazelbuild/bazel-gazelle",
			vcs:       "git",
			wantError: true, // stub should return an error
		},
	} {
		t.Run(tc.desc, func(t *testing.T) {
			rc := NewStubRemoteCache(nil)
			if gotCommit, gotTag, err := rc.Head(tc.remote, tc.vcs); err != nil {
				if !tc.wantError {
					t.Errorf("unexpected error: %v", err)
				}
			} else if tc.wantError {
				t.Errorf("unexpected success")
			} else if gotCommit != tc.wantCommit {
				t.Errorf("commit for %q: got %q ; want %q", tc.remote, gotCommit, tc.wantCommit)
			} else if gotTag != tc.wantTag {
				t.Errorf("tag for %q: got %q ; want %q", tc.remote, gotTag, tc.wantTag)
			}
		})
	}
}

func TestMod(t *testing.T) {
	for _, tc := range []struct {
		desc, importPath      string
		repos                 []Repo
		wantModPath, wantName string
		wantErr               bool
	}{
		{
			desc:       "no_special_cases",
			importPath: "golang.org/x/exp",
			wantErr:    true,
		}, {
			desc:       "known",
			importPath: "example.com/known/v2/foo",
			repos: []Repo{{
				Name:     "known",
				GoPrefix: "example.com/known",
			}},
			wantModPath: "example.com/known",
			wantName:    "known",
		}, {
			desc:       "semver_less_path_is_safe",
			importPath: "example.com/known/internal/endpoints",
			repos: []Repo{{
				Name:     "known",
				GoPrefix: "example.com/known",
			}, {
				Name:     "known_internal_endpoints_v2",
				GoPrefix: "example.com/known/internal/endpoints/v2",
			}},
			wantModPath: "example.com/known",
			wantName:    "known",
		}, {
			desc:        "lookup",
			importPath:  "example.com/stub/v2/foo",
			wantModPath: "example.com/stub/v2",
			wantName:    "com_example_stub_v2",
		},
	} {
		t.Run(tc.desc, func(t *testing.T) {
			rc := NewStubRemoteCache(tc.repos)
			modPath, name, err := rc.Mod(tc.importPath)
			if err != nil && tc.wantErr {
				return
			} else if err == nil && tc.wantErr {
				t.Error("want error; got success")
			} else if err != nil {
				t.Fatal(err)
			}
			if modPath != tc.wantModPath {
				t.Errorf("modPath: got %s; want %s", modPath, tc.wantModPath)
			}
			if name != tc.wantName {
				t.Errorf("name: got %s; want %s", name, tc.wantName)
			}
		})
	}
}

func TestModVersion(t *testing.T) {
	for _, tc := range []struct {
		desc, modPath, query           string
		repos                          []Repo
		wantName, wantVersion, wantSum string
	}{
		{
			desc:    "known",
			modPath: "example.com/known",
			query:   "latest",
			repos: []Repo{{
				Name:     "known",
				GoPrefix: "example.com/known",
			}},
			wantName:    "known",
			wantVersion: "v1.2.3",
			wantSum:     "h1:abcdef",
		}, {
			desc:        "unknown",
			modPath:     "example.com/unknown",
			query:       "latest",
			wantName:    "com_example_unknown",
			wantVersion: "v1.2.3",
			wantSum:     "h1:abcdef",
		},
	} {
		t.Run(tc.desc, func(t *testing.T) {
			rc := NewStubRemoteCache(tc.repos)
			name, version, sum, err := rc.ModVersion(tc.modPath, tc.query)
			if err != nil {
				t.Fatal(err)
			}
			if name != tc.wantName {
				t.Errorf("name: got %q; want %q", name, tc.wantName)
			}
			if version != tc.wantVersion {
				t.Errorf("version: got %q; want %q", version, tc.wantVersion)
			}
			if sum != tc.wantSum {
				t.Errorf("sum: got %q; want %q", sum, tc.wantSum)
			}
		})
	}
}
