// Copyright 2018 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 modfetch

import (
	"cmd/go/internal/module"
	"cmd/go/internal/semver"
	"fmt"
	"strings"
)

// Query looks up a revision of a given module given a version query string.
// The module must be a complete module path.
// The version must take one of the following forms:
//
//	- the literal string "latest", denoting the latest available tagged version
//	- v1.2.3, a semantic version string
//	- v1 or v1.2, an abbreviated semantic version string completed by adding zeroes (v1.0.0 or v1.2.0);
//	- >v1.2.3, denoting the earliest available version after v1.2.3
//	- <v1.2.3, denoting the latest available version before v1.2.3
//	- an RFC 3339 time stamp, denoting the latest available version at that time
//	- a Unix time expressed as seconds since 1970, denoting the latest available version at that time
//	- a repository commit identifier, denoting that version
//
// The time stamps can be followed by an optional @branch suffix to limit the
// result to revisions on a particular branch name.
//
func Query(path, vers string, allowed func(module.Version) bool) (*RevInfo, error) {
	if strings.HasPrefix(vers, "v") && semver.IsValid(vers) {
		// TODO: This turns query for "v2" into Stat "v2.0.0",
		// but probably it should allow checking for a branch named "v2".
		vers = semver.Canonical(vers)
		if allowed != nil && !allowed(module.Version{Path: path, Version: vers}) {
			return nil, fmt.Errorf("%s@%s excluded", path, vers)
		}

		// Fast path that avoids network overhead of Lookup (resolving path to repo host),
		// if we already have this stat information cached on disk.
		info, err := Stat(path, vers)
		if err == nil {
			return info, nil
		}
	}

	repo, err := Lookup(path)
	if err != nil {
		return nil, err
	}

	if semver.IsValid(vers) {
		return repo.Stat(vers)
	}
	if strings.HasPrefix(vers, ">") || strings.HasPrefix(vers, "<") || vers == "latest" {
		var op string
		if vers != "latest" {
			if !semver.IsValid(vers[1:]) {
				return nil, fmt.Errorf("invalid semantic version in range %s", vers)
			}
			op, vers = vers[:1], vers[1:]
		}
		versions, err := repo.Versions("")
		if err != nil {
			return nil, err
		}
		if len(versions) == 0 && vers == "latest" {
			return repo.Latest()
		}
		if vers == "latest" {
			for i := len(versions) - 1; i >= 0; i-- {
				if allowed == nil || allowed(module.Version{Path: path, Version: versions[i]}) {
					return repo.Stat(versions[i])
				}
			}
		} else if op == "<" {
			for i := len(versions) - 1; i >= 0; i-- {
				if semver.Compare(versions[i], vers) < 0 && (allowed == nil || allowed(module.Version{Path: path, Version: versions[i]})) {
					return repo.Stat(versions[i])
				}
			}
		} else {
			for i := 0; i < len(versions); i++ {
				if semver.Compare(versions[i], vers) > 0 && (allowed == nil || allowed(module.Version{Path: path, Version: versions[i]})) {
					return repo.Stat(versions[i])
				}
			}
		}
		return nil, fmt.Errorf("no matching versions for %s%s", op, vers)
	}
	// TODO: Time queries, maybe.

	return repo.Stat(vers)
}
