// Copyright 2022 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 pkgpattern

import (
	"regexp"
	"strings"
	"unicode/utf8"
)

// Note: most of this code was originally part of the cmd/go/internal/search
// package; it was migrated here in order to support the use case of
// commands other than cmd/go that need to accept package pattern args.

// TreeCanMatchPattern(pattern)(name) reports whether
// name or children of name can possibly match pattern.
// Pattern is the same limited glob accepted by MatchPattern.
func TreeCanMatchPattern(pattern string) func(name string) bool {
	wildCard := false
	if i := strings.Index(pattern, "..."); i >= 0 {
		wildCard = true
		pattern = pattern[:i]
	}
	return func(name string) bool {
		return len(name) <= len(pattern) && hasPathPrefix(pattern, name) ||
			wildCard && strings.HasPrefix(name, pattern)
	}
}

// MatchPattern(pattern)(name) reports whether
// name matches pattern. Pattern is a limited glob
// pattern in which '...' means 'any string' and there
// is no other special syntax.
// Unfortunately, there are two special cases. Quoting "go help packages":
//
// First, /... at the end of the pattern can match an empty string,
// so that net/... matches both net and packages in its subdirectories, like net/http.
// Second, any slash-separated pattern element containing a wildcard never
// participates in a match of the "vendor" element in the path of a vendored
// package, so that ./... does not match packages in subdirectories of
// ./vendor or ./mycode/vendor, but ./vendor/... and ./mycode/vendor/... do.
// Note, however, that a directory named vendor that itself contains code
// is not a vendored package: cmd/vendor would be a command named vendor,
// and the pattern cmd/... matches it.
func MatchPattern(pattern string) func(name string) bool {
	return matchPatternInternal(pattern, true)
}

// MatchSimplePattern returns a function that can be used to check
// whether a given name matches a pattern, where pattern is a limited
// glob pattern in which '...' means 'any string', with no other
// special syntax. There is one special case for MatchPatternSimple:
// according to the rules in "go help packages": a /... at the end of
// the pattern can match an empty string, so that net/... matches both
// net and packages in its subdirectories, like net/http.
func MatchSimplePattern(pattern string) func(name string) bool {
	return matchPatternInternal(pattern, false)
}

func matchPatternInternal(pattern string, vendorExclude bool) func(name string) bool {
	// Convert pattern to regular expression.
	// The strategy for the trailing /... is to nest it in an explicit ? expression.
	// The strategy for the vendor exclusion is to change the unmatchable
	// vendor strings to a disallowed code point (vendorChar) and to use
	// "(anything but that codepoint)*" as the implementation of the ... wildcard.
	// This is a bit complicated but the obvious alternative,
	// namely a hand-written search like in most shell glob matchers,
	// is too easy to make accidentally exponential.
	// Using package regexp guarantees linear-time matching.

	const vendorChar = "\x00"

	if vendorExclude && strings.Contains(pattern, vendorChar) || !utf8.ValidString(pattern) {
		return func(name string) bool { return false }
	}

	re := regexp.QuoteMeta(pattern)
	wild := `.*`
	if vendorExclude {
		wild = `[^` + vendorChar + `]*`
		re = replaceVendor(re, vendorChar)
		switch {
		case strings.HasSuffix(re, `/`+vendorChar+`/\.\.\.`):
			re = strings.TrimSuffix(re, `/`+vendorChar+`/\.\.\.`) + `(/vendor|/` + vendorChar + `/\.\.\.)`
		case re == vendorChar+`/\.\.\.`:
			re = `(/vendor|/` + vendorChar + `/\.\.\.)`
		}
	}
	if strings.HasSuffix(re, `/\.\.\.`) {
		re = strings.TrimSuffix(re, `/\.\.\.`) + `(/\.\.\.)?`
	}
	re = strings.ReplaceAll(re, `\.\.\.`, wild)

	reg := regexp.MustCompile(`^` + re + `$`)

	return func(name string) bool {
		if vendorExclude {
			if strings.Contains(name, vendorChar) {
				return false
			}
			name = replaceVendor(name, vendorChar)
		}
		return reg.MatchString(name)
	}
}

// hasPathPrefix reports whether the path s begins with the
// elements in prefix.
func hasPathPrefix(s, prefix string) bool {
	switch {
	default:
		return false
	case len(s) == len(prefix):
		return s == prefix
	case len(s) > len(prefix):
		if prefix != "" && prefix[len(prefix)-1] == '/' {
			return strings.HasPrefix(s, prefix)
		}
		return s[len(prefix)] == '/' && s[:len(prefix)] == prefix
	}
}

// replaceVendor returns the result of replacing
// non-trailing vendor path elements in x with repl.
func replaceVendor(x, repl string) string {
	if !strings.Contains(x, "vendor") {
		return x
	}
	elem := strings.Split(x, "/")
	for i := 0; i < len(elem)-1; i++ {
		if elem[i] == "vendor" {
			elem[i] = repl
		}
	}
	return strings.Join(elem, "/")
}
