// 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/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.QueryUpgradesAllError{
				MainModules: modload.MainModules.Versions(),
				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"
}
