// Copyright 2020 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 modget

import (
	"fmt"
	"path/filepath"
	"regexp"
	"strings"
	"sync"

	"cmd/go/internal/base"
	"cmd/go/internal/modload"
	"cmd/go/internal/search"
	"cmd/go/internal/str"

	"golang.org/x/mod/module"
)

// A query describes a command-line argument and the modules and/or packages
// to which that argument may resolve..
type query struct {
	// raw is the original argument, to be printed in error messages.
	raw string

	// rawVersion is the portion of raw corresponding to version, if any
	rawVersion string

	// pattern is the part of the argument before "@" (or the whole argument
	// if there is no "@"), which may match either packages (preferred) or
	// modules (if no matching packages).
	//
	// The pattern may also be "-u", for the synthetic query representing the -u
	// (“upgrade”)flag.
	pattern string

	// patternIsLocal indicates whether pattern is restricted to match only paths
	// local to the main module, such as absolute filesystem paths or paths
	// beginning with './'.
	//
	// A local pattern must resolve to one or more packages in the main module.
	patternIsLocal bool

	// version is the part of the argument after "@", or an implied
	// "upgrade" or "patch" if there is no "@". version specifies the
	// module version to get.
	version string

	// matchWildcard, if non-nil, reports whether pattern, which must be a
	// wildcard (with the substring "..."), matches the given package or module
	// path.
	matchWildcard func(path string) bool

	// canMatchWildcard, if non-nil, reports whether the module with the given
	// path could lexically contain a package matching pattern, which must be a
	// wildcard.
	canMatchWildcardInModule func(mPath string) bool

	// conflict is the first query identified as incompatible with this one.
	// conflict forces one or more of the modules matching this query to a
	// version that does not match version.
	conflict *query

	// candidates is a list of sets of alternatives for a path that matches (or
	// contains packages that match) the pattern. The query can be resolved by
	// choosing exactly one alternative from each set in the list.
	//
	// A path-literal query results in only one set: the path itself, which
	// may resolve to either a package path or a module path.
	//
	// A wildcard query results in one set for each matching module path, each
	// module for which the matching version contains at least one matching
	// package, and (if no other modules match) one candidate set for the pattern
	// overall if no existing match is identified in the build list.
	//
	// A query for pattern "all" results in one set for each package transitively
	// imported by the main module.
	//
	// The special query for the "-u" flag results in one set for each
	// otherwise-unconstrained package that has available upgrades.
	candidates   []pathSet
	candidatesMu sync.Mutex

	// pathSeen ensures that only one pathSet is added to the query per
	// unique path.
	pathSeen sync.Map

	// resolved contains the set of modules whose versions have been determined by
	// this query, in the order in which they were determined.
	//
	// The resolver examines the candidate sets for each query, resolving one
	// module per candidate set in a way that attempts to avoid obvious conflicts
	// between the versions resolved by different queries.
	resolved []module.Version

	// matchesPackages is true if the resolved modules provide at least one
	// package mathcing q.pattern.
	matchesPackages bool
}

// A pathSet describes the possible options for resolving a specific path
// to a package and/or module.
type pathSet struct {
	// path is a package (if "all" or "-u" or a non-wildcard) or module (if
	// wildcard) path that could be resolved by adding any of the modules in this
	// set. For a wildcard pattern that so far matches no packages, the path is
	// the wildcard pattern itself.
	//
	// Each path must occur only once in a query's candidate sets, and the path is
	// added implicitly to each pathSet returned to pathOnce.
	path string

	// pkgMods is a set of zero or more modules, each of which contains the
	// package with the indicated path. Due to the requirement that imports be
	// unambiguous, only one such module can be in the build list, and all others
	// must be excluded.
	pkgMods []module.Version

	// mod is either the zero Version, or a module that does not contain any
	// packages matching the query but for which the module path itself
	// matches the query pattern.
	//
	// We track this module separately from pkgMods because, all else equal, we
	// prefer to match a query to a package rather than just a module. Also,
	// unlike the modules in pkgMods, this module does not inherently exclude
	// any other module in pkgMods.
	mod module.Version

	err error
}

// errSet returns a pathSet containing the given error.
func errSet(err error) pathSet { return pathSet{err: err} }

// newQuery returns a new query parsed from the raw argument,
// which must be either path or path@version.
func newQuery(raw string) (*query, error) {
	pattern := raw
	rawVers := ""
	if i := strings.Index(raw, "@"); i >= 0 {
		pattern, rawVers = raw[:i], raw[i+1:]
		if strings.Contains(rawVers, "@") || rawVers == "" {
			return nil, fmt.Errorf("invalid module version syntax %q", raw)
		}
	}

	// If no version suffix is specified, assume @upgrade.
	// If -u=patch was specified, assume @patch instead.
	version := rawVers
	if version == "" {
		if getU.version == "" {
			version = "upgrade"
		} else {
			version = getU.version
		}
	}

	q := &query{
		raw:            raw,
		rawVersion:     rawVers,
		pattern:        pattern,
		patternIsLocal: filepath.IsAbs(pattern) || search.IsRelativePath(pattern),
		version:        version,
	}
	if strings.Contains(q.pattern, "...") {
		q.matchWildcard = search.MatchPattern(q.pattern)
		q.canMatchWildcardInModule = search.TreeCanMatchPattern(q.pattern)
	}
	if err := q.validate(); err != nil {
		return q, err
	}
	return q, nil
}

// validate reports a non-nil error if q is not sensible and well-formed.
func (q *query) validate() error {
	if q.patternIsLocal {
		if q.rawVersion != "" {
			return fmt.Errorf("can't request explicit version %q of path %q in main module", q.rawVersion, q.pattern)
		}
		return nil
	}

	if q.pattern == "all" {
		// If there is no main module, "all" is not meaningful.
		if !modload.HasModRoot() {
			return fmt.Errorf(`cannot match "all": %v`, modload.ErrNoModRoot)
		}
		if !versionOkForMainModule(q.version) {
			// TODO(bcmills): "all@none" seems like a totally reasonable way to
			// request that we remove all module requirements, leaving only the main
			// module and standard library. Perhaps we should implement that someday.
			return &modload.QueryMatchesMainModuleError{
				Pattern: q.pattern,
				Query:   q.version,
			}
		}
	}

	if search.IsMetaPackage(q.pattern) && q.pattern != "all" {
		if q.pattern != q.raw {
			return fmt.Errorf("can't request explicit version of standard-library pattern %q", q.pattern)
		}
	}

	return nil
}

// String returns the original argument from which q was parsed.
func (q *query) String() string { return q.raw }

// ResolvedString returns a string describing m as a resolved match for q.
func (q *query) ResolvedString(m module.Version) string {
	if m.Path != q.pattern {
		if m.Version != q.version {
			return fmt.Sprintf("%v (matching %s@%s)", m, q.pattern, q.version)
		}
		return fmt.Sprintf("%v (matching %v)", m, q)
	}
	if m.Version != q.version {
		return fmt.Sprintf("%s@%s (%s)", q.pattern, q.version, m.Version)
	}
	return q.String()
}

// isWildcard reports whether q is a pattern that can match multiple paths.
func (q *query) isWildcard() bool {
	return q.matchWildcard != nil || (q.patternIsLocal && strings.Contains(q.pattern, "..."))
}

// matchesPath reports whether the given path matches q.pattern.
func (q *query) matchesPath(path string) bool {
	if q.matchWildcard != nil {
		return q.matchWildcard(path)
	}
	return path == q.pattern
}

// canMatchInModule reports whether the given module path can potentially
// contain q.pattern.
func (q *query) canMatchInModule(mPath string) bool {
	if q.canMatchWildcardInModule != nil {
		return q.canMatchWildcardInModule(mPath)
	}
	return str.HasPathPrefix(q.pattern, mPath)
}

// pathOnce invokes f to generate the pathSet for the given path,
// if one is still needed.
//
// Note that, unlike sync.Once, pathOnce does not guarantee that a concurrent
// call to f for the given path has completed on return.
//
// pathOnce is safe for concurrent use by multiple goroutines, but note that
// multiple concurrent calls will result in the sets being added in
// nondeterministic order.
func (q *query) pathOnce(path string, f func() pathSet) {
	if _, dup := q.pathSeen.LoadOrStore(path, nil); dup {
		return
	}

	cs := f()

	if len(cs.pkgMods) > 0 || cs.mod != (module.Version{}) || cs.err != nil {
		cs.path = path
		q.candidatesMu.Lock()
		q.candidates = append(q.candidates, cs)
		q.candidatesMu.Unlock()
	}
}

// reportError logs err concisely using base.Errorf.
func reportError(q *query, err error) {
	errStr := err.Error()

	// If err already mentions all of the relevant parts of q, just log err to
	// reduce stutter. Otherwise, log both q and err.
	//
	// TODO(bcmills): Use errors.As to unpack these errors instead of parsing
	// strings with regular expressions.

	patternRE := regexp.MustCompile("(?m)(?:[ \t(\"`]|^)" + regexp.QuoteMeta(q.pattern) + "(?:[ @:;)\"`]|$)")
	if patternRE.MatchString(errStr) {
		if q.rawVersion == "" {
			base.Errorf("go get: %s", errStr)
			return
		}

		versionRE := regexp.MustCompile("(?m)(?:[ @(\"`]|^)" + regexp.QuoteMeta(q.version) + "(?:[ :;)\"`]|$)")
		if versionRE.MatchString(errStr) {
			base.Errorf("go get: %s", errStr)
			return
		}
	}

	if qs := q.String(); qs != "" {
		base.Errorf("go get %s: %s", qs, errStr)
	} else {
		base.Errorf("go get: %s", errStr)
	}
}

func reportConflict(pq *query, m module.Version, conflict versionReason) {
	if pq.conflict != nil {
		// We've already reported a conflict for the proposed query.
		// Don't report it again, even if it has other conflicts.
		return
	}
	pq.conflict = conflict.reason

	proposed := versionReason{
		version: m.Version,
		reason:  pq,
	}
	if pq.isWildcard() && !conflict.reason.isWildcard() {
		// Prefer to report the specific path first and the wildcard second.
		proposed, conflict = conflict, proposed
	}
	reportError(pq, &conflictError{
		mPath:    m.Path,
		proposed: proposed,
		conflict: conflict,
	})
}

type conflictError struct {
	mPath    string
	proposed versionReason
	conflict versionReason
}

func (e *conflictError) Error() string {
	argStr := func(q *query, v string) string {
		if v != q.version {
			return fmt.Sprintf("%s@%s (%s)", q.pattern, q.version, v)
		}
		return q.String()
	}

	pq := e.proposed.reason
	rq := e.conflict.reason
	modDetail := ""
	if e.mPath != pq.pattern {
		modDetail = fmt.Sprintf("for module %s, ", e.mPath)
	}

	return fmt.Sprintf("%s%s conflicts with %s",
		modDetail,
		argStr(pq, e.proposed.version),
		argStr(rq, e.conflict.version))
}

func versionOkForMainModule(version string) bool {
	return version == "upgrade" || version == "patch"
}
