package planparserv2

import (
	"fmt"

	"github.com/milvus-io/milvus/internal/proto/planpb"
)

var wildcards = map[byte]struct{}{
	// '_': {}, // TODO
	'%': {},
}

var escapeCharacter byte = '\\'

// hasWildcards returns true if pattern contains any wildcard.
func hasWildcards(pattern string) bool {
	l := len(pattern)
	i := l - 1
	for ; i >= 0; i-- {
		_, ok := wildcards[pattern[i]]
		if ok {
			if i > 0 && pattern[i-1] == escapeCharacter {
				i--
				continue
			}
			return true
		}
	}
	return false
}

// findLastNotOfWildcards find the last location not of last wildcard.
func findLastNotOfWildcards(pattern string) int {
	loc := len(pattern) - 1
	for ; loc >= 0; loc-- {
		_, ok := wildcards[pattern[loc]]
		if !ok {
			break
		}
		if ok {
			if loc > 0 && pattern[loc-1] == escapeCharacter {
				break
			}
		}
	}
	return loc
}

// translatePatternMatch translates pattern to related op type and operand.
func translatePatternMatch(pattern string) (op planpb.OpType, operand string, err error) {
	l := len(pattern)
	loc := findLastNotOfWildcards(pattern)

	if loc < 0 {
		// always match.
		return planpb.OpType_PrefixMatch, "", nil
	}

	exist := hasWildcards(pattern[:loc+1])
	if loc >= l-1 && !exist {
		// equal match.
		return planpb.OpType_Equal, pattern, nil
	}
	if !exist {
		// prefix match.
		return planpb.OpType_PrefixMatch, pattern[:loc+1], nil
	}

	return planpb.OpType_Invalid, "", fmt.Errorf(
		"unsupported pattern: %s, "+
			"only prefix pattern match like %s "+
			"and equal match like %s(no wildcards) are supported",
		pattern, "ab%", "ab")
}
