#!/usr/bin/env bash

JSON_HELPER="$(ctx::json_helper)"

function json::get()                    { python3 "$JSON_HELPER" get                    "$@" </dev/null; }
function json::set()                    { python3 "$JSON_HELPER" set                    "$@" </dev/null; }
function json::delete()                 { python3 "$JSON_HELPER" delete                 "$@" </dev/null; }
function json::append()                 { python3 "$JSON_HELPER" append                 "$@" </dev/null; }
function json::remove()                 { python3 "$JSON_HELPER" remove                 "$@" </dev/null; }
function json::cat()                    { python3 "$JSON_HELPER" cat                    "$@" </dev/null; }
function json::has_key()                { python3 "$JSON_HELPER" has_key                "$@" </dev/null; }
function json::filter_values()          { python3 "$JSON_HELPER" filter_values          "$@" </dev/null; }
function json::last_event()             { python3 "$JSON_HELPER" last_event             "$@" </dev/null; }
function json::events_for()             { python3 "$JSON_HELPER" events_for             "$@" </dev/null; }
function json::fw_events()              { WGCTL_DATETIME_FMT="$FMT_DATETIME_SHORT" python3 "$JSON_HELPER" fw_events "$@" "$(ctx::endpoint_cache)" </dev/null; }
function json::wg_events()              { WGCTL_DATETIME_FMT="$FMT_DATETIME_SHORT" python3 "$JSON_HELPER" wg_events "$@" "$(ctx::endpoint_cache)" </dev/null; }
function json::format_fw_event()        { echo "$1" | python3 "$JSON_HELPER" format_fw_event "$2"; }
function json::format_wg_event()        { echo "$1" | python3 "$JSON_HELPER" format_wg_event; }
function json::remove_events()          { python3 "$JSON_HELPER" remove_events          "$@" </dev/null; }
function json::follow_logs()            { WGCTL_DATETIME_FMT="$FMT_DATETIME" python3 "$JSON_HELPER" follow_logs "$@"; }
function json::count()                  { python3 "$JSON_HELPER" count                  "$@" </dev/null; }
function json::audit_fw_counts()        { python3 "$JSON_HELPER" audit_fw_counts        "$@" </dev/null; }
function json::peer_group_map()         { python3 "$JSON_HELPER" peer_group_map         "$@" </dev/null; }
function json::peer_groups()            { python3 "$JSON_HELPER" peer_groups            "$@" </dev/null; }
function json::peer_data()              { WGCTL_DATETIME_FMT="$FMT_DATETIME" python3 "$JSON_HELPER" peer_data   "$@" </dev/null; }
function json::iso_to_ts()              { python3 "$JSON_HELPER" iso_to_ts              "$@" </dev/null; }
function json::rule_list_data()         { python3 "$JSON_HELPER" rule_list_data         "$@" </dev/null; }
function json::group_list_data()        { python3 "$JSON_HELPER" group_list_data        "$@" </dev/null; }
function json::fmt_datetime()           { python3 "$JSON_HELPER" fmt_datetime           "$@" </dev/null; }
function json::create_rule()            { python3 "$JSON_HELPER" create_rule            "$@" </dev/null; }
function json::cleanup_config()         { python3 "$JSON_HELPER" cleanup_config         "$@" </dev/null; }
function json::remove_peer_block()      { python3 "$JSON_HELPER" remove_peer_block      "$@" </dev/null; }
function json::create_group()           { python3 "$JSON_HELPER" create_group           "$@" </dev/null; }
function json::parse_event()            { python3 "$JSON_HELPER" parse_event            "$@" </dev/null; }
function json::parse_fw_event()         { python3 "$JSON_HELPER" parse_fw_event         "$@" </dev/null; }
function json::remove_events_filtered() { python3 "$JSON_HELPER" remove_events_filtered "$@" </dev/null; }
function json::rule_resolve()           { python3 "$JSON_HELPER" rule_resolve           "$@" </dev/null; }
function json::rule_resolve_field()     { python3 "$JSON_HELPER" rule_resolve_field     "$@" </dev/null; }
function json::rule_inspect()           { python3 "$JSON_HELPER" rule_inspect           "$@" </dev/null; }
function json::find_rule_file()         { python3 "$JSON_HELPER" find_rule_file         "$@" </dev/null; }
function json::get_raw()                { python3 "$JSON_HELPER" get_raw                "$@" </dev/null; }
function json::count_resolved()         { python3 "$JSON_HELPER" count_resolved "$(ctx::rules)" "$@" </dev/null; }
function json::block_get()              { python3 "$JSON_HELPER" block_get              "$@" </dev/null; }
function json::block_is_blocked()       { python3 "$JSON_HELPER" block_is_blocked       "$@" </dev/null; }
function json::block_set_direct()       { python3 "$JSON_HELPER" block_set_direct       "$@" </dev/null; }
function json::block_add_group()        { python3 "$JSON_HELPER" block_add_group        "$@" </dev/null; }
function json::block_remove_group()     { python3 "$JSON_HELPER" block_remove_group     "$@" </dev/null; }
function json::block_add_rule()         { python3 "$JSON_HELPER" block_add_rule         "$@" </dev/null; }
function json::block_remove_rule()      { python3 "$JSON_HELPER" block_remove_rule      "$@" </dev/null; }
function json::block_get_rules()        { python3 "$JSON_HELPER" block_get_rules        "$@" </dev/null; }
function json::block_get_groups()       { python3 "$JSON_HELPER" block_get_groups       "$@" </dev/null; }
function json::block_get_direct()       { python3 "$JSON_HELPER" block_get_direct       "$@" </dev/null; }
function json::net_list()               { python3 "$JSON_HELPER" net_list               "$@" </dev/null; }
function json::net_show()               { python3 "$JSON_HELPER" net_show               "$@" </dev/null; }
function json::net_exists()             { python3 "$JSON_HELPER" net_exists             "$@" </dev/null; }
function json::net_add_service()        { python3 "$JSON_HELPER" net_add_service        "$@" </dev/null; }
function json::net_add_port()           { python3 "$JSON_HELPER" net_add_port           "$@" </dev/null; }
function json::net_remove()             { python3 "$JSON_HELPER" net_remove             "$@" </dev/null; }
function json::net_resolve()            { python3 "$JSON_HELPER" net_resolve            "$@" </dev/null; }
function json::net_reverse_lookup()     { python3 "$JSON_HELPER" net_reverse_lookup     "$@" </dev/null; }
function json::block_is_empty()         { python3 "$JSON_HELPER" block_is_empty         "$@" </dev/null; }
function json::group_has_peer()         { python3 "$JSON_HELPER" group_has_peer         "$@" </dev/null; }
function json::get_nested()             { python3 "$JSON_HELPER" get_nested             "$@" </dev/null; }
function json::set_nested()             { python3 "$JSON_HELPER" set_nested             "$@" </dev/null; }

# Subnet wrappers
function json::subnet_lookup()          { python3 "$JSON_HELPER" subnet_lookup        "$@" </dev/null; }
function json::subnet_type()            { python3 "$JSON_HELPER" subnet_type          "$@" </dev/null; }
function json::subnet_tunnel_mode()     { python3 "$JSON_HELPER" subnet_tunnel_mode   "$@" </dev/null; }
function json::subnet_for_ip()          { python3 "$JSON_HELPER" subnet_for_ip        "$@" </dev/null; }
function json::subnet_list()            { python3 "$JSON_HELPER" subnet_list          "$@" </dev/null; }
function json::subnet_show()            { python3 "$JSON_HELPER" subnet_show          "$@" </dev/null; }
function json::subnet_add()             { python3 "$JSON_HELPER" subnet_add           "$@" </dev/null; }
function json::subnet_remove()          { python3 "$JSON_HELPER" subnet_remove        "$@" </dev/null; }
function json::subnet_rename()          { python3 "$JSON_HELPER" subnet_rename        "$@" </dev/null; }
function json::subnet_peers()           { python3 "$JSON_HELPER" subnet_peers         "$@" </dev/null; }
function json::subnet_exists()          { python3 "$JSON_HELPER" subnet_exists        "$@" </dev/null; }
function json::subnet_default_rule()    { python3 "$JSON_HELPER" subnet_default_rule  "$@" </dev/null; }
function json::subnet_list_names()      { python3 "$JSON_HELPER" subnet_list_names    "$@" </dev/null; }
 
# Identity wrappers
function json::identity_list()          { python3 "$JSON_HELPER" identity_list        "$@" </dev/null; }
function json::identity_show()          { python3 "$JSON_HELPER" identity_show        "$@" </dev/null; }
function json::identity_add_peer()      { python3 "$JSON_HELPER" identity_add_peer    "$@" </dev/null; }
function json::identity_remove_peer()   { python3 "$JSON_HELPER" identity_remove_peer "$@" </dev/null; }
function json::identity_remove()        { python3 "$JSON_HELPER" identity_remove      "$@" </dev/null; }
function json::identity_next_index()    { python3 "$JSON_HELPER" identity_next_index  "$@" </dev/null; }
function json::identity_peers()         { python3 "$JSON_HELPER" identity_peers       "$@" </dev/null; }
function json::identity_migrate()       { python3 "$JSON_HELPER" identity_migrate     "$@" </dev/null; }
function json::identity_infer()         { python3 "$JSON_HELPER" identity_infer       "$@" </dev/null; }
function json::identity_exists()        { python3 "$JSON_HELPER" identity_exists      "$@" </dev/null; }

# Identity rule wrappers (1:N)
function json::identity_rules()         { python3 "$JSON_HELPER" identity_rules       "$@" </dev/null; }
function json::identity_add_rule()      { python3 "$JSON_HELPER" identity_add_rule    "$@" </dev/null; }
function json::identity_remove_rule()   { python3 "$JSON_HELPER" identity_remove_rule "$@" </dev/null; }
function json::identity_clear_rules()   { python3 "$JSON_HELPER" identity_clear_rules "$@" </dev/null; }
function json::identity_has_rule()      { python3 "$JSON_HELPER" identity_has_rule    "$@" </dev/null; }

# Policy wrappers
function json::policy_get()             { python3 "$JSON_HELPER" policy_get           "$@" </dev/null; }
function json::policy_list()            { python3 "$JSON_HELPER" policy_list          "$@" </dev/null; }
function json::policy_exists()          { python3 "$JSON_HELPER" policy_exists        "$@" </dev/null; }
function json::policy_add()             { python3 "$JSON_HELPER" policy_add           "$@" </dev/null; }
function json::policy_remove()          { python3 "$JSON_HELPER" policy_remove        "$@" </dev/null; }
function json::policy_set_field()       { python3 "$JSON_HELPER" policy_set_field     "$@" </dev/null; }
function json::subnet_policy()          { python3 "$JSON_HELPER" subnet_policy        "$@" </dev/null; }

# Activity Monitor
function json::activity_aggregate()     { python3 "$JSON_HELPER" activity_aggregate "$@" </dev/null; }
function json::iso_to_ts()              { python3 "$JSON_HELPER" iso_to_ts          "$@" </dev/null; }
 
# Hosts Resolution
function json::hosts_list()             { python3 "$JSON_HELPER" hosts_list   "$@" </dev/null; }
function json::hosts_show()             { python3 "$JSON_HELPER" hosts_show   "$@" </dev/null; }
function json::hosts_add()              { python3 "$JSON_HELPER" hosts_add    "$@" </dev/null; }
function json::hosts_remove()           { python3 "$JSON_HELPER" hosts_remove "$@" </dev/null; }
function json::hosts_exists()           { python3 "$JSON_HELPER" hosts_exists "$@" </dev/null; }
function json::hosts_lookup()           { python3 "$JSON_HELPER" hosts_lookup "$@" </dev/null; }

# Peer History
function json::peer_history_lookup()    { python3 "$JSON_HELPER" peer_history_lookup "$(ctx::data)/peer-history" "$1" </dev/null; }

function json::clean_handshakes()       { python3 "$JSON_HELPER" clean_handshakes "$@" </dev/null; }
function json::batch_resolve()          { python3 "$JSON_HELPER" batch_resolve "$(ctx::hosts)" "$(ctx::net)" "$@" </dev/null; }

# JSON Envelopes
function json::envelope() {
  local command="${1:-}" count="${2:-0}"
  # Reads JSON array from stdin, wraps in envelope
  local data
  data=$(cat)
  local ts
  ts=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
  printf '{"ok":true,"command":"%s","data":%s,"meta":{"count":%s,"generated_at":"%s"}}\n' \
    "$command" "$data" "$count" "$ts"
}
 
function json::error_envelope() {
  local command="${1:-}" error="${2:-}"
  local ts
  ts=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
  printf '{"ok":false,"command":"%s","error":"%s","meta":{"generated_at":"%s"}}\n' \
    "$command" "$error" "$ts"
}

# Config
function json::config_load() { python3 "$JSON_HELPER" config_load "$1" </dev/null; }

function json::block_history_record()     { python3 "$JSON_HELPER" block_history_record "$@" </dev/null; }
function json::block_history_unblock()    { python3 "$JSON_HELPER" block_history_unblock "$@" </dev/null; }
function json::block_history_list()       { python3 "$JSON_HELPER" block_history_list "$@" </dev/null; }
function json::block_history_list_all()   { python3 "$JSON_HELPER" block_history_list_all "$@" </dev/null; }

function json::endpoint_cache_get()       { python3 "$JSON_HELPER" endpoint_cache_get "$@" </dev/null; }

# Accept Events
function json::accept_events()            { python3 "$JSON_HELPER" accept_events    "$@" </dev/null; }
function json::accept_aggregate()         { python3 "$JSON_HELPER" accept_aggregate "$@" </dev/null; }
function json::batch_resolve_dest()       { python3 "$JSON_HELPER" batch_resolve_dest "$(ctx::net)" "$(ctx::hosts)" "$@" </dev/null; }

function json::peer_transfer() {
  ACTIVITY_TOTAL_LOW="$(config::activity_total_low)" \
  ACTIVITY_TOTAL_MED="$(config::activity_total_med)" \
  ACTIVITY_TOTAL_HIGH="$(config::activity_total_high)" \
  python3 "$JSON_HELPER" peer_transfer "$@" </dev/null
}
function json::peer_transfer_delta() {
  ACTIVITY_CURRENT_LOW="$(config::activity_current_low)" \
  ACTIVITY_CURRENT_MED="$(config::activity_current_med)" \
  ACTIVITY_CURRENT_HIGH="$(config::activity_current_high)" \
  python3 "$JSON_HELPER" peer_transfer_delta "$@" </dev/null
}

# Importer
function json::import_peer()      { python3 "$JSON_HELPER" import_peer      "$@" </dev/null; }
function json::import_identity()  { python3 "$JSON_HELPER" import_identity  "$@" </dev/null; }
function json::import_full()      { python3 "$JSON_HELPER" import_full      "$@" </dev/null; }
function json::import_get_field() { python3 "$JSON_HELPER" import_get_field "$@" </dev/null; }