#!/bin/sh
CARGO_TARGET_DIR=${CARGO_TARGET_DIR:-${PWD}/target}
POLICY_PATH=${POLICY_PATH:-/opt/kumomta/etc/policy/init.lua}

KUMOD=${KUMOD:-kumod}

if ! test -x ${KUMOD} ; then
  for candidate in /opt/kumomta/sbin/kumod "${CARGO_TARGET_DIR}/release/kumod" "${CARGO_TARGET_DIR}/debug/kumod" ; do
    if test -x "${candidate}" ; then
      KUMOD="${candidate}"
      break;
    fi
  done

  if ! test -x "${KUMOD}" ; then
    echo "Couldn't find kumod"
    exit 1
  fi
fi

script=$(mktemp)
trap "rm -f -- '$script'" EXIT
cat >${script} <<-'EOT'
local kumo = require 'kumo'
dofile(os.getenv('POLICY_PATH'))

local function print_help()
  print [[
Resolves the effective shaping configuration for a domain and
optionally for the source that you specify, plus the steady-state
throughput ceilings implied by that configuration.

Usage:
  resolve-shaping-domain [OPTIONS] DOMAIN_NAME [SOURCE_NAME]

If SOURCE_NAME is omitted, 'unspecified' will be used for the
source name.

Output format:
  By default, the scheduled-queue config, egress path config and a
  human-readable ceilings block are printed as pretty TOML. The
  ceilings fold in constraints from both configs. The flags below
  request machine-readable JSON for individual sections instead.

Options:
  --json-config        Print the egress path config as pretty JSON
                       instead of TOML. Equivalent to the legacy
                       output of this script.
  --json-queue-config  Print the scheduled-queue config as pretty
                       JSON instead of TOML.
  --json-constraints   Print the computed throughput ceilings as
                       pretty JSON instead of the human-readable
                       block.
  -h, --help           Show this help text.

If multiple --json-* flags are passed, the JSON documents are
emitted in order. The combined output is several separate JSON
values, not a single document; consumers should parse them
independently.
]]
end

kumo.on('main', function(...)
  local args = { ... }
  local json_config = false
  local json_queue_config = false
  local json_constraints = false
  local positional = {}

  for _, arg in ipairs(args) do
    if arg == '-h' or arg == '--help' then
      print_help()
      return
    elseif arg == '--json-config' then
      json_config = true
    elseif arg == '--json-queue-config' then
      json_queue_config = true
    elseif arg == '--json-constraints' then
      json_constraints = true
    elseif string.sub(arg, 1, 2) == '--' then
      io.stderr:write('unknown option: ' .. arg .. '\n')
      os.exit(2)
    else
      table.insert(positional, arg)
    end
  end

  if #positional < 1 then
    print_help()
    os.exit(1)
  end

  local domain = positional[1]
  local source = positional[2] or 'unspecified'

  local site_name = domain
  local ok, mx = pcall(kumo.dns.lookup_mx, domain)
  if ok then
    site_name = mx.site_name
  end

  local queue_config = kumo.invoke_get_queue_config(domain)
  local path_config =
    kumo.invoke_get_egress_path_config(domain, source, site_name)
  local queue_constraints =
    kumo.compute_queue_config_constraints(queue_config)
  local constraints = kumo.compute_egress_path_config_constraints(
    path_config,
    queue_constraints
  )

  local any_json = json_config or json_queue_config or json_constraints
  local emit_text_sections = not any_json

  if emit_text_sections then
    print '--- scheduled queue config ---'
    print ''
    print(kumo.format_queue_config_toml(queue_config))
    print '--- egress path config ---'
    print ''
    print(kumo.format_egress_path_config_toml(path_config))
    print '--- effective ceilings ---'
    print ''
    io.write(kumo.format_egress_path_config_constraints(constraints))
  end

  local emitted_any_json = false
  if json_queue_config then
    print(kumo.serde.json_encode_pretty(queue_config))
    emitted_any_json = true
  end
  if json_config then
    if emitted_any_json then
      print ''
    end
    print(kumo.serde.json_encode_pretty(path_config))
    emitted_any_json = true
  end
  if json_constraints then
    if emitted_any_json then
      print ''
    end
    print(kumo.serde.json_encode_pretty(constraints))
  end
end)
EOT

is_user_root () { [ "${EUID:-$(id -u)}" -eq 0 ]; }

RUN_AS_USER=""
if is_user_root ; then
  chmod a+rx $script
  RUN_AS_USER="--user kumod"
fi

POLICY_PATH="${POLICY_PATH}" \
  ${KUMOD} $RUN_AS_USER --policy $script --script -- "$@"
