// 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 source constructs public URLs that link to the source files in a module. It
// can be used to build references to Go source code, or to any other files in a
// module.
//
// Of course, the module zip file contains all the files in the module. This
// package attempts to find the origin of the zip file, in a repository that is
// publicly readable, and constructs links to that repo. While a module zip file
// could in theory come from anywhere, including a non-public location, this
// package recognizes standard module path patterns and construct repository
// URLs from them, like the go command does.
package source

//
// Much of this code was adapted from
// https://go.googlesource.com/gddo/+/refs/heads/master/gosrc
// and
// https://go.googlesource.com/go/+/refs/heads/master/src/cmd/go/internal/get

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"path"
	"path/filepath"
	"regexp"
	"slices"
	"strconv"
	"strings"

	"golang.org/x/net/context/ctxhttp"
	"golang.org/x/pkgsite/internal/derrors"
	"golang.org/x/pkgsite/internal/log"
	"golang.org/x/pkgsite/internal/stdlib"
	"golang.org/x/pkgsite/internal/trace"
	"golang.org/x/pkgsite/internal/version"
)

// Info holds source information about a module, used to generate URLs referring
// to directories, files and lines.
type Info struct {
	repoURL   string       // URL of repo containing module; exported for DB schema compatibility
	moduleDir string       // directory of module relative to repo root
	commit    string       // tag or ID of commit corresponding to version
	templates urlTemplates // for building URLs
}

// RepoURL returns a URL for the home page of the repository.
func (i *Info) RepoURL() string {
	if i == nil {
		return ""
	}
	if i.templates.Repo == "" {
		// The default repo template is just "{repo}".
		return i.repoURL
	}
	return expand(i.templates.Repo, map[string]string{
		"repo": i.repoURL,
	})
}

// ModuleURL returns a URL for the home page of the module.
func (i *Info) ModuleURL() string {
	return i.DirectoryURL("")
}

// DirectoryURL returns a URL for a directory relative to the module's home directory.
func (i *Info) DirectoryURL(dir string) string {
	if i == nil {
		return ""
	}
	return strings.TrimSuffix(expand(i.templates.Directory, map[string]string{
		"repo":       i.repoURL,
		"importPath": path.Join(strings.TrimPrefix(i.repoURL, "https://"), dir),
		"commit":     i.commit,
		"dir":        path.Join(i.moduleDir, dir),
	}), "/")
}

// FileURL returns a URL for a file whose pathname is relative to the module's home directory.
func (i *Info) FileURL(pathname string) string {
	if i == nil {
		return ""
	}
	dir, base := path.Split(pathname)
	return expand(i.templates.File, map[string]string{
		"repo":       i.repoURL,
		"importPath": path.Join(strings.TrimPrefix(i.repoURL, "https://"), dir),
		"commit":     i.commit,
		"dir":        dir,
		"file":       path.Join(i.moduleDir, pathname),
		"base":       base,
	})
}

// LineURL returns a URL referring to a line in a file relative to the module's home directory.
func (i *Info) LineURL(pathname string, line int) string {
	if i == nil {
		return ""
	}
	dir, base := path.Split(pathname)
	return expand(i.templates.Line, map[string]string{
		"repo":       i.repoURL,
		"importPath": path.Join(strings.TrimPrefix(i.repoURL, "https://"), dir),
		"commit":     i.commit,
		"file":       path.Join(i.moduleDir, pathname),
		"dir":        dir,
		"base":       base,
		"line":       strconv.Itoa(line),
	})
}

// RawURL returns a URL referring to the raw contents of a file relative to the
// module's home directory.
func (i *Info) RawURL(pathname string) string {
	if i == nil {
		return ""
	}
	// Some templates don't support raw content serving.
	if i.templates.Raw == "" {
		return ""
	}
	moduleDir := i.moduleDir
	// Special case: the standard library's source module path is set to "src",
	// which is correct for source file links. But the README is at the repo
	// root, not in the src directory. In other words,
	// Module.Units[0].Readme.FilePath is not relative to
	// Module.Units[0].SourceInfo.moduleDir, as it is for every other module.
	// Correct for that here.
	if i.repoURL == stdlib.GoSourceRepoURL {
		moduleDir = ""
	}
	return expand(i.templates.Raw, map[string]string{
		"repo":   i.repoURL,
		"commit": i.commit,
		"file":   path.Join(moduleDir, pathname),
	})
}

// map of common urlTemplates
var urlTemplatesByKind = map[string]urlTemplates{
	"github":    githubURLTemplates,
	"gitlab":    gitlabURLTemplates,
	"bitbucket": bitbucketURLTemplates,
}

// jsonInfo is a Go struct describing the JSON structure of an INFO.
type jsonInfo struct {
	RepoURL   string
	ModuleDir string
	Commit    string
	// Store common templates efficiently by setting this to a short string
	// we look up in a map. If Kind != "", then Templates == nil.
	Kind      string        `json:",omitempty"`
	Templates *urlTemplates `json:",omitempty"`
}

// MarshalJSON returns the Info encoded for storage in the database.
func (i *Info) MarshalJSON() (_ []byte, err error) {
	defer derrors.Wrap(&err, "MarshalJSON")

	ji := &jsonInfo{
		RepoURL:   i.repoURL,
		ModuleDir: i.moduleDir,
		Commit:    i.commit,
	}
	// Store common templates efficiently, by name.
	for kind, templs := range urlTemplatesByKind {
		if i.templates == templs {
			ji.Kind = kind
			break
		}
	}
	if ji.Kind == "" && i.templates != (urlTemplates{}) {
		ji.Templates = &i.templates
	}
	return json.Marshal(ji)
}

func (i *Info) UnmarshalJSON(data []byte) (err error) {
	defer derrors.Wrap(&err, "UnmarshalJSON(data)")

	var ji jsonInfo
	if err := json.Unmarshal(data, &ji); err != nil {
		return err
	}
	i.repoURL = trimVCSSuffix(ji.RepoURL)
	i.moduleDir = ji.ModuleDir
	i.commit = ji.Commit
	if ji.Kind != "" {
		i.templates = urlTemplatesByKind[ji.Kind]
	} else if ji.Templates != nil {
		i.templates = *ji.Templates
	}
	return nil
}

type Client struct {
	// client used for HTTP requests. It is mutable for testing purposes.
	// If nil, then moduleInfoDynamic will return nil, nil; also for testing.
	httpClient *http.Client
}

// New constructs a *Client using the provided *http.Client.
func NewClient(httpClient *http.Client) *Client {
	return &Client{httpClient: httpClient}
}

// NewClientForTesting returns a Client suitable for testing. It returns the
// same results as an ordinary client for statically recognizable paths, but
// always returns a nil *Info for dynamic paths (those requiring HTTP requests).
func NewClientForTesting() *Client {
	return &Client{}
}

// doURL makes an HTTP request using the given url and method. It returns an
// error if the request returns an error. If only200 is true, it also returns an
// error if any status code other than 200 is returned.
func (c *Client) doURL(ctx context.Context, method, url string, only200 bool) (_ *http.Response, err error) {
	defer derrors.Wrap(&err, "doURL(ctx, client, %q, %q)", method, url)

	if c == nil || c.httpClient == nil {
		return nil, fmt.Errorf("c.httpClient cannot be nil")
	}
	req, err := http.NewRequest(method, url, nil)
	if err != nil {
		return nil, err
	}
	resp, err := ctxhttp.Do(ctx, c.httpClient, req)
	if err != nil {
		return nil, err
	}
	if only200 && resp.StatusCode != 200 {
		resp.Body.Close()
		return nil, fmt.Errorf("status %s", resp.Status)
	}
	return resp, nil
}

// ModuleInfo determines the repository corresponding to the module path. It
// returns a URL to that repo, as well as the directory of the module relative
// to the repo root.
//
// ModuleInfo may fetch from arbitrary URLs, so it can be slow.
func ModuleInfo(ctx context.Context, client *Client, modulePath, v string) (info *Info, err error) {
	defer derrors.Wrap(&err, "source.ModuleInfo(ctx, %q, %q)", modulePath, v)
	ctx, span := trace.StartSpan(ctx, "source.ModuleInfo")
	defer span.End()

	// The example.com domain can never be real; it is reserved for testing
	// (https://en.wikipedia.org/wiki/Example.com). Treat it as if it used
	// GitHub templates.
	if strings.HasPrefix(modulePath, "example.com/") {
		return NewGitHubInfo("https://"+modulePath, "", v), nil
	}

	repo, relativeModulePath, templates, transformCommit, err := matchStatic(modulePath)
	if err != nil {
		info, err = moduleInfoDynamic(ctx, client, modulePath, v)
		if err != nil {
			return nil, err
		}
	} else {
		commit, isHash := commitFromVersion(v, relativeModulePath)
		if transformCommit != nil {
			commit = transformCommit(commit, isHash)
		}
		info = &Info{
			repoURL:   trimVCSSuffix("https://" + repo),
			moduleDir: relativeModulePath,
			commit:    commit,
			templates: templates,
		}
	}
	if info != nil {
		adjustVersionedModuleDirectory(ctx, client, info)
	}
	if strings.HasPrefix(modulePath, "golang.org/") {
		adjustGoRepoInfo(info, modulePath, version.IsPseudo(v))
	}
	return info, nil
	// TODO(golang/go#39627): support launchpad.net, including the special case
	// in cmd/go/internal/get/vcs.go.
}

func NewStdlibInfo(version string) (_ *Info, err error) {
	defer derrors.Wrap(&err, "NewStdlibInfo(%q)", version)

	commit, err := stdlib.TagForVersion(version)
	if err != nil {
		return nil, err
	}

	templates := csopensourceTemplates
	templates.Raw = "https://github.com/golang/go/raw/{commit}/{file}"
	return &Info{
		repoURL:   stdlib.GoSourceRepoURL,
		moduleDir: stdlib.Directory(version),
		commit:    commit,
		templates: templates,
	}, nil
}

// csNonXRepos is a set of repos hosted at https://cs.opensource.google/go,
// that are not an x/repo.
var csNonXRepos = map[string]bool{
	"dl":        true,
	"proposal":  true,
	"vscode-go": true,
}

// csXRepos is the set of repos hosted at https://cs.opensource.google/go,
// that have a x/ prefix.
//
// x/scratch is not included.
var csXRepos = map[string]bool{
	"x/arch":       true,
	"x/benchmarks": true,
	"x/blog":       true,
	"x/build":      true,
	"x/crypto":     true,
	"x/debug":      true,
	"x/example":    true,
	"x/exp":        true,
	"x/image":      true,
	"x/mobile":     true,
	"x/mod":        true,
	"x/net":        true,
	"x/oauth2":     true,
	"x/perf":       true,
	"x/pkgsite":    true,
	"x/playground": true,
	"x/review":     true,
	"x/sync":       true,
	"x/sys":        true,
	"x/talks":      true,
	"x/term":       true,
	"x/text":       true,
	"x/time":       true,
	"x/tools":      true,
	"x/tour":       true,
	"x/vgo":        true,
	"x/website":    true,
	"x/xerrors":    true,
}

func adjustGoRepoInfo(info *Info, modulePath string, isHash bool) {
	suffix := strings.TrimPrefix(modulePath, "golang.org/")

	// Validate that this is a repo that exists on
	// https://cs.opensource.google/go. Otherwise, default to the existing
	// info.
	parts := strings.Split(suffix, "/")
	if len(parts) >= 2 {
		suffix = parts[0] + "/" + parts[1]
	}
	if strings.HasPrefix(suffix, "x/") {
		if !csXRepos[suffix] {
			return
		}
	} else if !csNonXRepos[suffix] {
		return
	}

	// rawURL needs to be set before info.templates is changed.
	rawURL := fmt.Sprintf(
		"https://github.com/golang/%s/raw/{commit}/{file}", strings.TrimPrefix(suffix, "x/"))

	info.repoURL = fmt.Sprintf("https://cs.opensource.google/go/%s", suffix)
	info.templates = csopensourceTemplates
	info.templates.Raw = rawURL

	if isHash {
		// When we have a pseudoversion, info.commit will be an actual commit
		// instead of a tag.
		//
		// https://cs.opensource.google/go/* has short commits hardcoded to 8
		// chars. Commits shorter or longer will not work, unless it is the full
		// commit hash.
		info.commit = info.commit[0:8]
	}
}

// matchStatic matches the given module or repo path against a list of known
// patterns. It returns the repo name, the module path relative to the repo
// root, and URL templates if there is a match.
//
// The relative module path may not be correct in all cases: it is wrong if it
// ends in a version that is not part of the repo directory structure, because
// the repo follows the "major branch" convention for versions 2 and above.
// E.g. this function could return "foo/v2", but the module files live under "foo"; the
// "/v2" is part of the module path (and the import paths of its packages) but
// is not a subdirectory. This mistake is corrected in adjustVersionedModuleDirectory,
// once we have all the information we need to fix it.
//
// repo + "/" + relativeModulePath is often, but not always, equal to
// moduleOrRepoPath. It is not when the argument is a module path that uses the
// go command's general syntax, which ends in a ".vcs" (e.g. ".git", ".hg") that
// is neither part of the repo nor the suffix. For example, if the argument is
//
//	github.com/a/b/c
//
// then repo="github.com/a/b" and relativeModulePath="c"; together they make up the module path.
// But if the argument is
//
//	example.com/a/b.git/c
//
// then repo="example.com/a/b" and relativeModulePath="c"; the ".git" is omitted, since it is neither
// part of the repo nor part of the relative path to the module within the repo.
func matchStatic(moduleOrRepoPath string) (repo, relativeModulePath string, _ urlTemplates, transformCommit transformCommitFunc, _ error) {
	for _, pat := range patterns {
		matches := pat.re.FindStringSubmatch(moduleOrRepoPath)
		if matches == nil {
			continue
		}
		var repo string
		for i, n := range pat.re.SubexpNames() {
			if n == "repo" {
				repo = matches[i]
				break
			}
		}
		// Special case: git.apache.org has a go-import tag that points to
		// github.com/apache, but it's not quite right (the repo prefix is
		// missing a ".git"), so handle it here.
		const apacheDomain = "git.apache.org/"
		if strings.HasPrefix(repo, apacheDomain) {
			repo = strings.Replace(repo, apacheDomain, "github.com/apache/", 1)
		}
		// Special case: module paths are blitiri.com.ar/go/..., but repos are blitiri.com.ar/git/r/...
		if strings.HasPrefix(repo, "blitiri.com.ar/") {
			repo = strings.Replace(repo, "/go/", "/git/r/", 1)
		}
		relativeModulePath = strings.TrimPrefix(moduleOrRepoPath, matches[0])
		relativeModulePath = strings.TrimPrefix(relativeModulePath, "/")
		return repo, relativeModulePath, pat.templates, pat.transformCommit, nil
	}
	return "", "", urlTemplates{}, nil, derrors.NotFound
}

// moduleInfoDynamic uses the go-import and go-source meta tags to construct an Info.
func moduleInfoDynamic(ctx context.Context, client *Client, modulePath, version string) (_ *Info, err error) {
	defer derrors.Wrap(&err, "moduleInfoDynamic(ctx, client, %q, %q)", modulePath, version)

	if client.httpClient == nil {
		return nil, nil // for testing
	}

	sourceMeta, err := fetchMeta(ctx, client, modulePath)
	if err != nil {
		return nil, err
	}
	// Don't check that the tag information at the repo root prefix is the same
	// as in the module path. It was done for us by the proxy and/or go command.
	// (This lets us merge information from the go-import and go-source tags.)

	// sourceMeta contains some information about where the module's source lives. But there
	// are some problems:
	// - We may only have a go-import tag, not a go-source tag, so we don't have URL templates for
	//   building URLs to files and directories.
	// - Even if we do have a go-source tag, its URL template format predates
	//   versioning, so the URL templates won't provide a way to specify a
	//   version or commit.
	//
	// We resolve these problems as follows:
	// 1. First look at the repo URL from the tag. If that matches a known hosting site, use the
	//    URL templates corresponding to that site and ignore whatever's in the tag.
	// 2. Then look at the URL templates to see if they match a known pattern, and use the templates
	//    from that pattern. For example, the meta tags for gopkg.in/yaml.v2 only mention github
	//    in the URL templates, like "https://github.com/go-yaml/yaml/tree/v2.2.3{/dir}". We can observe
	//    that that template begins with a known pattern--a GitHub repo, ignore the rest of it, and use the
	//    GitHub URL templates that we know.
	repoURL := sourceMeta.repoURL
	_, _, templates, transformCommit, _ := matchStatic(removeHTTPScheme(repoURL))
	// If err != nil, templates will be the zero value, so we can ignore it (same just below).
	if templates == (urlTemplates{}) {
		var repo string
		repo, _, templates, transformCommit, _ = matchStatic(removeHTTPScheme(sourceMeta.dirTemplate))
		if templates == (urlTemplates{}) {
			if err == nil {
				templates, transformCommit = matchLegacyTemplates(ctx, sourceMeta)
				repoURL = strings.TrimSuffix(repoURL, ".git")
			} else {
				log.Infof(ctx, "no templates for repo URL %q from meta tag: err=%v", sourceMeta.repoURL, err)
			}
		} else {
			// Use the repo from the template, not the original one.
			repoURL = "https://" + repo
		}
	}
	dir := strings.TrimPrefix(strings.TrimPrefix(modulePath, sourceMeta.repoRootPrefix), "/")
	dir = path.Join(sourceMeta.repoSubdir, dir)
	commit, isHash := commitFromVersion(version, dir)
	if transformCommit != nil {
		commit = transformCommit(commit, isHash)
	}
	return &Info{
		repoURL:   strings.TrimSuffix(repoURL, "/"),
		moduleDir: dir,
		commit:    commit,
		templates: templates,
	}, nil
}

// List of template regexps and their corresponding likely templates,
// used by matchLegacyTemplates below.
var legacyTemplateMatches = []struct {
	fileRegexp      *regexp.Regexp
	templates       urlTemplates
	transformCommit transformCommitFunc
}{
	{
		regexp.MustCompile(`/src/branch/\w+\{/dir\}/\{file\}#L\{line\}$`),
		giteaURLTemplates, giteaTransformCommit,
	},
	{
		regexp.MustCompile(`/src/\w+\{/dir\}/\{file\}#L\{line\}$`),
		giteaURLTemplates, nil,
	},
	{
		regexp.MustCompile(`/-/blob/\w+\{/dir\}/\{file\}#L\{line\}$`),
		gitlabURLTemplates, nil,
	},
	{
		regexp.MustCompile(`/tree\{/dir\}/\{file\}#n\{line\}$`),
		fdioURLTemplates, fdioTransformCommit,
	},
}

// matchLegacyTemplates matches the templates from the go-source meta tag
// against some known patterns to guess the version-aware URL templates. If it
// can't find a match, it falls back using the go-source templates with some
// small replacements. These will not be version-aware but will still serve
// source at a fixed commit, which is better than nothing.
func matchLegacyTemplates(ctx context.Context, sm *sourceMeta) (_ urlTemplates, transformCommit transformCommitFunc) {
	if sm.fileTemplate == "" {
		return urlTemplates{}, nil
	}
	for _, ltm := range legacyTemplateMatches {
		if ltm.fileRegexp.MatchString(sm.fileTemplate) {
			return ltm.templates, ltm.transformCommit
		}
	}
	log.Infof(ctx, "matchLegacyTemplates: no matches for repo URL %q; replacing", sm.repoURL)
	rep := strings.NewReplacer(
		"{/dir}/{file}", "/{file}",
		"{dir}/{file}", "{file}",
		"{/dir}", "/{dir}")
	line := rep.Replace(sm.fileTemplate)
	file := line
	if i := strings.LastIndexByte(line, '#'); i > 0 {
		file = line[:i]
	}
	return urlTemplates{
		Repo:      sm.repoURL,
		Directory: rep.Replace(sm.dirTemplate),
		File:      file,
		Line:      line,
	}, nil
}

// adjustVersionedModuleDirectory changes info.moduleDir if necessary to
// correctly reflect the repo structure. info.moduleDir will be wrong if it has
// a suffix "/vN" for N > 1, and the repo uses the "major branch" convention,
// where modules at version 2 and higher live on branches rather than
// subdirectories. See https://research.swtch.com/vgo-module for a discussion of
// the "major branch" vs. "major subdirectory" conventions for organizing a
// repo.
func adjustVersionedModuleDirectory(ctx context.Context, client *Client, info *Info) {
	dirWithoutVersion := removeVersionSuffix(info.moduleDir)
	if info.moduleDir == dirWithoutVersion {
		return
	}
	// moduleDir does have a "/vN" for N > 1. To see if that is the actual directory,
	// fetch the go.mod file from it.
	res, err := client.doURL(ctx, "HEAD", info.FileURL("go.mod"), true)
	// On any failure, assume that the right directory is the one without the version.
	if err != nil {
		info.moduleDir = dirWithoutVersion
	} else {
		res.Body.Close()
	}
}

// removeHTTPScheme removes an initial "http://" or "https://" from url.
// The result can be used to match against our static patterns.
// If the URL uses a different scheme, it won't be removed and it won't
// match any patterns, as intended.
func removeHTTPScheme(url string) string {
	for _, prefix := range []string{"https://", "http://"} {
		if strings.HasPrefix(url, prefix) {
			return url[len(prefix):]
		}
	}
	return url
}

// removeVersionSuffix returns s with "/vN" removed if N is an integer > 1.
// Otherwise it returns s.
func removeVersionSuffix(s string) string {
	dir, base := path.Split(s)
	if !strings.HasPrefix(base, "v") {
		return s
	}
	if n, err := strconv.Atoi(base[1:]); err != nil || n < 2 {
		return s
	}
	return strings.TrimSuffix(dir, "/")
}

type transformCommitFunc func(commit string, isHash bool) string

// Patterns for determining repo and URL templates from module paths or repo
// URLs. Each regexp must match a prefix of the target string, and must have a
// group named "repo".
var patterns = []struct {
	pattern   string // uncompiled regexp
	templates urlTemplates
	re        *regexp.Regexp
	// transformCommit may alter the commit before substitution
	transformCommit transformCommitFunc
}{
	{
		pattern:   `^(?P<repo>github\.com/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)`,
		templates: githubURLTemplates,
	},
	{
		// Assume that any site beginning with "github." works like github.com.
		pattern:   `^(?P<repo>github\.[a-z0-9A-Z.-]+/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)(\.git|$)`,
		templates: githubURLTemplates,
	},
	{
		pattern:   `^(?P<repo>bitbucket\.org/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)`,
		templates: bitbucketURLTemplates,
	},
	{
		// Gitlab repos can have multiple path components.
		pattern:   `^(?P<repo>gitlab\.com/[^.]+)(\.git|$)`,
		templates: gitlabURLTemplates,
	},
	{
		// Assume that any site beginning with "gitlab." works like gitlab.com.
		pattern:   `^(?P<repo>gitlab\.[a-z0-9A-Z.-]+/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)(\.git|$)`,
		templates: gitlabURLTemplates,
	},
	{
		pattern:   `^(?P<repo>gitee\.com/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)(\.git|$)`,
		templates: githubURLTemplates,
	},
	{
		pattern: `^(?P<repo>git\.sr\.ht/~[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)`,
		templates: urlTemplates{
			Directory: "{repo}/tree/{commit}/{dir}",
			File:      "{repo}/tree/{commit}/{file}",
			Line:      "{repo}/tree/{commit}/{file}#L{line}",
			Raw:       "{repo}/blob/{commit}/{file}",
		},
	},
	{
		pattern:         `^(?P<repo>git\.fd\.io/[a-z0-9A-Z_.\-]+)`,
		templates:       fdioURLTemplates,
		transformCommit: fdioTransformCommit,
	},
	{
		pattern:   `^(?P<repo>git\.pirl\.io/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)`,
		templates: gitlabURLTemplates,
	},
	{
		pattern:   `^(?P<repo>git\.glasklar\.is/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)`,
		templates: gitlabURLTemplates,
	},
	{
		pattern:         `^(?P<repo>gitea\.com/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)(\.git|$)`,
		templates:       giteaURLTemplates,
		transformCommit: giteaTransformCommit,
	},
	{
		// Assume that any site beginning with "gitea." works like gitea.com.
		pattern:         `^(?P<repo>gitea\.[a-z0-9A-Z.-]+/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)(\.git|$)`,
		templates:       giteaURLTemplates,
		transformCommit: giteaTransformCommit,
	},
	{
		pattern:         `^(?P<repo>go\.isomorphicgo\.org/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)(\.git|$)`,
		templates:       giteaURLTemplates,
		transformCommit: giteaTransformCommit,
	},
	{
		pattern:         `^(?P<repo>git\.openprivacy\.ca/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)(\.git|$)`,
		templates:       giteaURLTemplates,
		transformCommit: giteaTransformCommit,
	},
	{
		pattern:         `^(?P<repo>codeberg\.org/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)(\.git|$)`,
		templates:       giteaURLTemplates,
		transformCommit: giteaTransformCommit,
	},
	{
		pattern: `^(?P<repo>gogs\.[a-z0-9A-Z.-]+/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)(\.git|$)`,
		// Gogs uses the same basic structure as Gitea, but omits the type of
		// commit ("tag" or "commit"), so we don't need a transformCommit
		// function. Gogs does not support short hashes, but we create those
		// URLs anyway. See gogs/gogs#6242.
		templates: giteaURLTemplates,
	},
	{
		pattern: `^(?P<repo>dmitri\.shuralyov\.com\/.+)$`,
		templates: urlTemplates{
			Repo:      "{repo}/...",
			Directory: "https://gotools.org/{importPath}?rev={commit}",
			File:      "https://gotools.org/{importPath}?rev={commit}#{base}",
			Line:      "https://gotools.org/{importPath}?rev={commit}#{base}-L{line}",
		},
	},
	{
		pattern: `^(?P<repo>blitiri\.com\.ar/go/.+)$`,
		templates: urlTemplates{
			Repo:      "{repo}",
			Directory: "{repo}/b/master/t/{dir}",
			File:      "{repo}/b/master/t/{dir}f={file}.html",
			Line:      "{repo}/b/master/t/{dir}f={file}.html#line-{line}",
		},
	},

	// Patterns that match the general go command pattern, where they must have
	// a ".git" repo suffix in an import path. If matching a repo URL from a meta tag,
	// there is no ".git".
	{
		pattern:   `^(?P<repo>[^.]+\.googlesource\.com/[^.]+)(\.git|$)`,
		templates: googlesourceURLTemplates,
	},
	{
		pattern:   `^(?P<repo>git\.apache\.org/[^.]+)(\.git|$)`,
		templates: githubURLTemplates,
	},
	// General syntax for the go command. We can extract the repo and directory, but
	// we don't know the URL templates.
	// Must be last in this list.
	{
		pattern:   `(?P<repo>([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?(/~?[A-Za-z0-9_.\-]+)+?)\.(bzr|fossil|git|hg|svn)`,
		templates: urlTemplates{},
	},
}

func init() {
	for i := range patterns {
		re := regexp.MustCompile(patterns[i].pattern)
		// The pattern regexp must contain a group named "repo".
		found := slices.Contains(re.SubexpNames(), "repo")
		if !found {
			panic(fmt.Sprintf("pattern %s missing <repo> group", patterns[i].pattern))
		}
		patterns[i].re = re
	}
}

// giteaTransformCommit transforms commits for the Gitea code hosting system.
func giteaTransformCommit(commit string, isHash bool) string {
	// Hashes use "commit", tags use "tag".
	// Short hashes are supported as of v1.14.0.
	if isHash {
		return "commit/" + commit
	}
	return "tag/" + commit
}

func fdioTransformCommit(commit string, isHash bool) string {
	// hashes use "?id=", tags use "?h="
	p := "h"
	if isHash {
		p = "id"
	}
	return fmt.Sprintf("%s=%s", p, commit)
}

// urlTemplates describes how to build URLs from bits of source information.
// The fields are exported for JSON encoding.
//
// The template variables are:
//
//   - {repo}       - Repository URL with "https://" prefix ("https://example.com/myrepo").
//   - {importPath} - Package import path ("example.com/myrepo/mypkg").
//   - {commit}     - Tag name or commit hash corresponding to version ("v0.1.0" or "1234567890ab").
//   - {dir}        - Path to directory of the package, relative to repo root ("mypkg").
//   - {file}       - Path to file containing the identifier, relative to repo root ("mypkg/file.go").
//   - {base}       - Base name of file containing the identifier, including file extension ("file.go").
//   - {line}       - Line number for the identifier ("41").
type urlTemplates struct {
	Repo      string `json:",omitempty"` // Optional URL template for the repository home page, with {repo}. If left empty, a default template "{repo}" is used.
	Directory string // URL template for a directory, with {repo}, {importPath}, {commit}, {dir}.
	File      string // URL template for a file, with {repo}, {importPath}, {commit}, {file}, {base}.
	Line      string // URL template for a line, with {repo}, {importPath}, {commit}, {file}, {base}, {line}.
	Raw       string // Optional URL template for the raw contents of a file, with {repo}, {commit}, {file}.
}

var (
	githubURLTemplates = urlTemplates{
		Directory: "{repo}/tree/{commit}/{dir}",
		File:      "{repo}/blob/{commit}/{file}",
		Line:      "{repo}/blob/{commit}/{file}#L{line}",
		Raw:       "{repo}/raw/{commit}/{file}",
	}

	bitbucketURLTemplates = urlTemplates{
		Directory: "{repo}/src/{commit}/{dir}",
		File:      "{repo}/src/{commit}/{file}",
		Line:      "{repo}/src/{commit}/{file}#lines-{line}",
		Raw:       "{repo}/raw/{commit}/{file}",
	}
	giteaURLTemplates = urlTemplates{
		Directory: "{repo}/src/{commit}/{dir}",
		File:      "{repo}/src/{commit}/{file}",
		Line:      "{repo}/src/{commit}/{file}#L{line}",
		Raw:       "{repo}/raw/{commit}/{file}",
	}
	googlesourceURLTemplates = urlTemplates{
		Directory: "{repo}/+/{commit}/{dir}",
		File:      "{repo}/+/{commit}/{file}",
		Line:      "{repo}/+/{commit}/{file}#{line}",
		// Gitiles has no support for serving raw content at this time.
	}
	gitlabURLTemplates = urlTemplates{
		Directory: "{repo}/-/tree/{commit}/{dir}",
		File:      "{repo}/-/blob/{commit}/{file}",
		Line:      "{repo}/-/blob/{commit}/{file}#L{line}",
		Raw:       "{repo}/-/raw/{commit}/{file}",
	}
	fdioURLTemplates = urlTemplates{
		Directory: "{repo}/tree/{dir}?{commit}",
		File:      "{repo}/tree/{file}?{commit}",
		Line:      "{repo}/tree/{file}?{commit}#n{line}",
		Raw:       "{repo}/plain/{file}?{commit}",
	}
	csopensourceTemplates = urlTemplates{
		Directory: "{repo}/+/{commit}:{dir}",
		File:      "{repo}/+/{commit}:{file}",
		Line:      "{repo}/+/{commit}:{file};l={line}",
		// Gitiles has no support for serving raw content at this time.
	}
)

// commitFromVersion returns a string that refers to a commit corresponding to version.
// It also reports whether the returned value is a commit hash.
// The string may be a tag, or it may be the hash or similar unique identifier of a commit.
// The second argument is the module path relative to the repo root.
func commitFromVersion(vers, relativeModulePath string) (commit string, isHash bool) {
	// Commit for the module: either a sha for pseudoversions, or a tag.
	v := strings.TrimSuffix(vers, "+incompatible")
	if version.IsPseudo(v) {
		// Use the commit hash at the end.
		return v[strings.LastIndex(v, "-")+1:], true
	} else {
		// The tags for a nested module begin with the relative module path of the module,
		// removing a "/vN" suffix if N > 1.
		prefix := removeVersionSuffix(relativeModulePath)
		if prefix != "" {
			return prefix + "/" + v, false
		}
		return v, false
	}
}

// trimVCSSuffix removes a VCS suffix from a repo URL in selected cases.
//
// The Go command allows a VCS suffix on a repo, like github.com/foo/bar.git. But
// some code hosting sites don't support all paths constructed from such URLs.
// For example, GitHub will redirect github.com/foo/bar.git to github.com/foo/bar,
// but will 404 on github.com/goo/bar.git/tree/master and any other URL with a
// non-empty path.
//
// To be conservative, we remove the suffix only in cases where we know it's
// wrong.
func trimVCSSuffix(repoURL string) string {
	if !strings.HasSuffix(repoURL, ".git") {
		return repoURL
	}
	if strings.HasPrefix(repoURL, "https://github.com/") || strings.HasPrefix(repoURL, "https://gitlab.com/") {
		return strings.TrimSuffix(repoURL, ".git")
	}
	return repoURL
}

// The following code copied from cmd/go/internal/get:

// expand rewrites s to replace {k} with match[k] for each key k in match.
func expand(s string, match map[string]string) string {
	// We want to replace each match exactly once, and the result of expansion
	// must not depend on the iteration order through the map.
	// A strings.Replacer has exactly the properties we're looking for.
	oldNew := make([]string, 0, 2*len(match))
	for k, v := range match {
		oldNew = append(oldNew, "{"+k+"}", v)
	}
	return strings.NewReplacer(oldNew...).Replace(s)
}

// NewGitHubInfo creates a source.Info with GitHub URL templates.
// It is for testing only.
func NewGitHubInfo(repoURL, moduleDir, commit string) *Info {
	return &Info{
		repoURL:   trimVCSSuffix(repoURL),
		moduleDir: moduleDir,
		commit:    commit,
		templates: githubURLTemplates,
	}
}

// NewStdlibInfoForTest returns a source.Info for the standard library at the given
// semantic version. It panics if the version does not correspond to a Go release
// tag. It is for testing only.
func NewStdlibInfoForTest(version string) *Info {
	info, err := NewStdlibInfo(version)
	if err != nil {
		panic(err)
	}
	return info
}

// FilesInfo returns an Info that links to a path in the server's /files
// namespace. The same path needs to be installed via frontend.Server.InstallFS.
func FilesInfo(dir string) *Info {
	// The repo and directory patterns need a final slash. Without it,
	// http.FileServer redirects instead of serving the directory contents, with
	// confusing results.
	return &Info{
		repoURL: path.Join("/files", filepath.ToSlash(dir)),
		templates: urlTemplates{
			Repo:      "{repo}/",
			Directory: "{repo}/{dir}/",
			File:      "{repo}/{file}",
			Line:      "{repo}/{file}#L{line}", // not supported now, but maybe someday
			Raw:       "{repo}/{file}",
		},
	}
}
