#!/usr/bin/env rq

# This sets the input file to the iata.json file. Note that the script needs
# to be executed from the same directory as the `data` folder.
# rq: input ./data/iata.json

# Before running the main query that produces the desired output, run the
# `check_codes` rule, which has a side-effect of crashing the script if the
# user didn't supply any codes as arguments.
# rq: silent-query data.script.check_codes

# The output from this script is determined by the query we put here. Note that
# since we didn't include a `package` statement, the script file is implied to
# have `package script`.
# rq: query data.script.output

# Cause output to be displayed in YAML format.
# rq: output-format yaml

codes := rq.args()

# Make sure that the user supplied at least one code. If not, exit with a
# helpful error.
check_codes {
	count(codes) == 0
	rq.error("usage: iata_info IATA_CODE [IATA_CODE]*")
}

# This is a partial rule keyed on the airport codes we got from the user as
# arguments. For each code we produce a pretty printed string.
output[code] = info {

	# code is any element of the codes array.
	code := codes[_]

	# The chosen code must appear in the input object; this statement is
	# only truthy if it does, so the rest of the rule body won't execute
	# if it isn't.
	input[code]

	# Produce our pretty printed info. By assigning the result of sprintf
	# to info, which appeared on the right hand side of the `=` in the rule
	# head, we are associating that result with the key `code`, which we
	# assigned above.
	info := sprintf("%s in %s, %s", [input[code].name, input[code].city, input[code].country])

}

# This creates an alternate case in the partial rule for the situation where a
# user-provided IATA code didn't appear in our database. The `not input[code]`
# is truthy if an only if the chosen `code` does not appear as a key in the
# input object.
#
# Because we had `input[code]` in the other rule body for the `output` partial
# rule, and we have `not input[code]` in this one, we can grantee that the two
# rule bodies will be disjoint and never produce an ambiguous assignment to
# `output[code]`.
output[code] = info {

	code := codes[_]
	not input[code]

	info := sprintf("no data found for IATA code '%s'", [code])
}
