// 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 module defines the module.Version type
// along with support code.
package module

import (
	"fmt"
	"strings"
	"unicode"
	"unicode/utf8"

	"cmd/go/internal/semver"
)

// A Version is defined by a module path and version pair.
type Version struct {
	Path string

	// Version is usually a semantic version in canonical form.
	// There are two exceptions to this general rule.
	// First, the top-level target of a build has no specific version
	// and uses Version = "".
	// Second, during MVS calculations the version "none" is used
	// to represent the decision to take no version of a given module.
	Version string
}

// Check checks that a given module path, version pair is valid.
// In addition to the path being a valid module path
// and the version being a valid semantic version,
// the two must correspond.
// For example, the path "yaml/v2" only corresponds to
// semantic versions beginning with "v2.".
func Check(path, version string) error {
	if err := CheckPath(path); err != nil {
		return err
	}
	if !semver.IsValid(version) {
		return fmt.Errorf("malformed semantic version %v", version)
	}
	vm := semver.Major(version)
	_, pathVersion, _ := SplitPathVersion(path)

	if strings.HasPrefix(pathVersion, ".") {
		// Special-case gopkg.in path requirements.
		pathVersion = pathVersion[1:] // cut .
		if vm == pathVersion {
			return nil
		}
	} else {
		// Standard path requirements.
		if pathVersion != "" {
			pathVersion = pathVersion[1:] // cut /
		}
		if vm == "v0" || vm == "v1" {
			vm = ""
		}
		if vm == pathVersion {
			return nil
		}
		if pathVersion == "" {
			pathVersion = "v0 or v1"
		}
	}
	return fmt.Errorf("mismatched module path %v and version %v (want %v)", path, version, pathVersion)
}

// firstPathOK reports whether r can appear in the first element of a module path.
// The first element of the path must be an LDH domain name, at least for now.
func firstPathOK(r rune) bool {
	return r == '-' || r == '.' ||
		'0' <= r && r <= '9' ||
		'A' <= r && r <= 'Z' ||
		'a' <= r && r <= 'z'
}

// pathOK reports whether r can appear in a module path.
// Paths must avoid potentially problematic ASCII punctuation
// and control characters but otherwise can be any Unicode printable character,
// as defined by Go's IsPrint.
func pathOK(r rune) bool {
	if r < utf8.RuneSelf {
		return r == '+' || r == ',' || r == '-' || r == '.' || r == '/' || r == '_' || r == '~' ||
			'0' <= r && r <= '9' ||
			'A' <= r && r <= 'Z' ||
			'a' <= r && r <= 'z'
	}
	return unicode.IsPrint(r)
}

// CheckPath checks that a module path is valid.
func CheckPath(path string) error {
	if !utf8.ValidString(path) {
		return fmt.Errorf("malformed module path %q: invalid UTF-8", path)
	}
	if path == "" {
		return fmt.Errorf("malformed module path %q: empty string", path)
	}

	i := strings.Index(path, "/")
	if i < 0 {
		i = len(path)
	}
	if i == 0 {
		return fmt.Errorf("malformed module path %q: leading slash", path)
	}
	if !strings.Contains(path[:i], ".") {
		return fmt.Errorf("malformed module path %q: missing dot in first path element", path)
	}
	if path[i-1] == '.' {
		return fmt.Errorf("malformed module path %q: trailing dot in first path element", path)
	}
	if path[0] == '.' {
		return fmt.Errorf("malformed module path %q: leading dot in first path element", path)
	}
	if path[0] == '-' {
		return fmt.Errorf("malformed module path %q: leading dash in first path element", path)
	}
	if strings.Contains(path, "..") {
		return fmt.Errorf("malformed module path %q: double dot", path)
	}
	if strings.Contains(path, "//") {
		return fmt.Errorf("malformed module path %q: double slash", path)
	}
	for _, r := range path[:i] {
		if !firstPathOK(r) {
			return fmt.Errorf("malformed module path %q: invalid char %q in first path element", path, r)
		}
	}
	if path[len(path)-1] == '/' {
		return fmt.Errorf("malformed module path %q: trailing slash", path)
	}
	for _, r := range path {
		if !pathOK(r) {
			return fmt.Errorf("malformed module path %q: invalid char %q", path, r)
		}
	}
	if _, _, ok := SplitPathVersion(path); !ok {
		return fmt.Errorf("malformed module path %q: invalid version %s", path, path[strings.LastIndex(path, "/")+1:])
	}
	return nil
}

// SplitPathVersion returns prefix and major version such that prefix+pathMajor == path
// and version is either empty or "/vN" for N >= 2.
// As a special case, gopkg.in paths are recognized directly;
// they require ".vN" instead of "/vN", and for all N, not just N >= 2.
func SplitPathVersion(path string) (prefix, pathMajor string, ok bool) {
	if strings.HasPrefix(path, "gopkg.in/") {
		return splitGopkgIn(path)
	}

	i := len(path)
	dot := false
	for i > 0 && ('0' <= path[i-1] && path[i-1] <= '9' || path[i-1] == '.') {
		if path[i-1] == '.' {
			dot = true
		}
		i--
	}
	if i <= 1 || path[i-1] != 'v' || path[i-2] != '/' {
		return path, "", true
	}
	prefix, pathMajor = path[:i-2], path[i-2:]
	if dot || len(pathMajor) <= 2 || pathMajor[2] == '0' || pathMajor == "/v1" {
		return path, "", false
	}
	return prefix, pathMajor, true
}

// splitGopkgIn is like SplitPathVersion but only for gopkg.in paths.
func splitGopkgIn(path string) (prefix, pathMajor string, ok bool) {
	if !strings.HasPrefix(path, "gopkg.in/") {
		return path, "", false
	}
	i := len(path)
	for i > 0 && ('0' <= path[i-1] && path[i-1] <= '9') {
		i--
	}
	if i <= 1 || path[i-1] != 'v' || path[i-2] != '.' {
		// All gopkg.in paths must end in vN for some N.
		return path, "", false
	}
	prefix, pathMajor = path[:i-2], path[i-2:]
	if len(pathMajor) <= 2 || pathMajor[2] == '0' && pathMajor != ".v0" {
		return path, "", false
	}
	return prefix, pathMajor, true
}

// MatchPathMajor reports whether the semantic version v
// matches the path major version pathMajor.
func MatchPathMajor(v, pathMajor string) bool {
	m := semver.Major(v)
	if pathMajor == "" {
		return m == "v0" || m == "v1"
	}
	return (pathMajor[0] == '/' || pathMajor[0] == '.') && m == pathMajor[1:]
}
