// Issues: #667, #695, #622

// Comparing against bottom is not officially supported by the spec.
// In practice it is used for a variety of purposes.
//
// TODO: It should really be replaced with two builtins:
//
//    - exists(reference): check if a certain field exists.
//    - isvalid(value):    check if a certain value is valid (recursively).
//
// For now it implements something in between these two: it fails if a value
// resolves to an error, but not necessarily if it does so recursively.
// Although adding a recursive check is easy, it will break existing
// configurations, as a recursive evaluation will trigger cycles where these
// are perhaps not expected.

// To verify these tests, each result should have a field
//
//     X: "user@example.com"
//
// for the large and medium examples and
//
//     X: "message: hello"
//
// for the simple example.
-- in.cue --
import "regexp"

simple: {
	#message: #"^(message: (?P<message>.*))?$"#

	p1: {
		@test(permute, count=24)

		X: "message: hello"
		#aux: {
			if Y.message == _|_ {
				message: ""
			}
			if Y.message != _|_ {
				message: "message: " + Y.message
			}
		}

		Y: regexp.FindNamedSubmatch(#message, X)
		X: #aux.message
		@test(eq, {
			X: "message: hello"
			#aux: {message: "message: hello"}
			Y: {message: "hello"}
		})
	}
}

medium: {
	#userHostPort: #"^((?P<userinfo>[[:alnum:]]*)@)?(?P<host>[[:alnum:].]+)$"#

	p1: {
		@test(permute, count=120)

		Y: {
			userinfo: "user"
			host:     "mod.test"
		}

		// X: "user@example.com"
		X: #X.userinfo + #X.host

		#X: {
			// userinfo: "user@"
			// host:     "mod.test"

			if Y.userinfo == _|_ {
				userinfo: ""
			}
			if Y.userinfo != _|_ {
				userinfo: Y.userinfo + "@"
			}

			host: Y.host
		}

		Y: {
			// userinfo: "user"
			// host:     "mod.test"

			if #Y.userinfo != _|_ {
				userinfo: #Y.userinfo
			}

			host: #Y.host
		}

		#Y: regexp.FindNamedSubmatch(#userHostPort, X)
		@test(eq, {
			Y: {userinfo: "user", host: "mod.test"}
			X: "user@mod.test"
			#X: {userinfo: "user@", host: "mod.test"}
			#Y: {host: "mod.test", userinfo: "user"}
		})
	}
}
-- out/todo.txt --
medium.p1-p4: field ordering of userinfo/host in #Y differs between v2 (host first) and v3 (userinfo first).
-- out/eval/stats --
Leaks:  0
Freed:  22
Reused: 7
Allocs: 15
Retain: 0

Unifications: 22
Conjuncts:    38
Disjuncts:    0

NumCloseIDs: 16
