#!/usr/bin/env luajit
-- SPDX-License-Identifier: GPL-3.0-or-later
-- Work around OS X stripping dyld variables
cli_bin = 'luajit scripts/kresd-query.lua'
libdir = os.getenv('DYLD_LIBRARY_PATH')
if libdir then
	cli_bin = string.format('DYLD_LIBRARY_PATH="%s" %s', libdir, cli_bin)
end
-- Parse CLI arguments
local function help(rc)
	print(string.format([[
Usage: %s [-vdh46D] [-c class] [-t type]
          [-f keyfile] hostname
  Queries the DNS for information.
  The hostname is looked up for IP4, IP6 and mail.
  Use the -v option to see DNSSEC security information.
    -t type     what type to look for.
    -c class    what class to look for, if not class IN.
    -C confstr  additional kresd-style configuration.
    -D          DNSSEC enable with default root anchor
    -f keyfile  read trust anchors from file, with lines as -y.
    -v          be more verbose, shows nodata and security.
    -d          debug, traces the action, -d -d shows more.
    -4          use ipv4 network, avoid ipv6.
    -6          use ipv6 network, avoid ipv4.
    -h          show this usage help.]],
    arg[0]))
	return rc
end

-- Parse CLI arguments
if #arg < 1 then
	return help(1)
end
local qtypes, qclass, qname = {}, 'IN', nil
local verbose, config = false, {}
k = 1 while k <= #arg do
	local v = arg[k]
	if v == '-h' or v == '--help' then
		return help(0)
	elseif v == '-C' then
		k = k + 1
		table.insert(config, arg[k])
	elseif v == '-D' then
		table.insert(config, 'trust_anchors.add_file("root.keys")')
	elseif v == '-f' then
		k = k + 1
		table.insert(config, string.format('trust_anchors.add_file("%s")', arg[k]))
	elseif v == '-v' then
		verbose = true
	elseif v == '-d' then
		verbose = true
		table.insert(config, 'log_level("debug")')
	elseif v == '-4' then
		table.insert(config, 'net.ipv6 = false')
	elseif v == '-6' then
		table.insert(config, 'net.ipv4 = false')
	elseif v == '-c' then
		k = k + 1
		qclass = arg[k]:upper()
	elseif v == '-t' then
		k = k + 1
		table.insert(qtypes, arg[k]:upper())
	elseif v:byte() == string.byte('-') then
		return help(1)
	else
		qname = v
		-- Check if name is an IP addresses
		-- @TODO: convert to domain name and make a PTR lookup
	end
	k = k + 1
end
if not qname then
	return help(1)
end
if #qtypes == 0 then
	qtypes = {'A', 'AAAA', 'MX'}
end
-- Assemble config/query
for _, qtype in ipairs(qtypes) do
	query = string.format('-t %s -c %s %s', qtype, qclass, qname)
	capture = string.format([[
	local qname = "%s"
	local qtype = "%s"
	local qverbose = %s]], qname, qtype, tostring(verbose))..[[
	local qry = req:resolved()
	local section = pkt:rrsets(kres.section.ANSWER)
	for i = 1, #section do
		local rr = section[i]
		for k = 1, rr.rrs.count do
			local rdata = rr:tostring(k - 1)
			local owner = kres.dname2str(rr:owner())
			if qverbose then
				if not qry.flags.DNSSEC_WANT or qry.flags.DNSSEC_INSECURE then
						rdata = rdata .. " (insecure)"
				else
						rdata = rdata .. " (secure)"
				end
			end
			if rr.type == kres.type.A then
				print(string.format("%s has address %s", owner, rdata))
			elseif rr.type == kres.type.AAAA then
				print(string.format("%s has IPv6 address %s", owner, rdata))
			elseif rr.type == kres.type.MX then
				print(string.format("%s mail is handled by %s", owner, rdata))
			elseif rr.type == kres.type.CNAME then
				print(string.format("%s is an alias for %s", owner, rdata))
			else
				print(string.format("%s has %s record %s", owner, qtype, rdata))
			end
		end
	end
	]]
	os.execute(string.format('%s -C \'%s\' %s \'%s\'', cli_bin, table.concat(config, ' '), query, capture))
end