// A stage controlled from a program: levels sent to an Art-Net node with their sequence numbers,
// a fade at a steady frame rate, nodes found with ArtPoll, the same levels over sACN (E1.31), and
// a listener of this program's own reading what lands on a port.
//
//   ARTNET_NODE=2.0.0.10 quillo run artnet.qwe      then open http://localhost:8080/scene and /poll
//
// ARTNET_POLL_TO is where ArtPoll goes: a broadcast address, 2.255.255.255 unless set. SACN_HOST
// sends sACN to one receiver; without it, to the universe's multicast address.

use "artnet.qwer"

let NODE = env("ARTNET_NODE", "2.0.0.10")
let SACN = env("SACN_HOST", "")
let LISTEN = int(env("ARTNET_LISTEN_PORT", "6455"))

artnet_listen("mine", LISTEN)

// Spots on channels 1 to 3, a dimmer on 10; numbers 1, 2, 3 per universe.
route GET /scene {
    let a = artnet_send(NODE, "0:1:3", { "1": 255, "2": 128, "3": 64, "10": 200 })?
    let b = artnet_send(NODE, "0:1:3", [255, 128, 64])?
    let other = artnet_send(NODE, 0, [10, 20])?
    { first: a, second: b.sequence, other_universe: other.sequence }
}

route GET /fade {
    let f = artnet_fade(NODE, 1, [0, 0, 0, 0], [255, 255, 0, 100], 300, 40)?
    { frames: f.frames, on_time: f.ms >= 280 && f.ms < 1500 }
}

route GET /bad = {
    level: artnet_send(NODE, 0, [300]).error,
    channel: artnet_send(NODE, 0, { "513": 1 }).error,
    universe: artnet_send(NODE, "0:16:0", [1]).error,
    too_many: artnet_send(NODE, 0, range(513) | map((i) => 0)).error,
    sacn_zero: artnet_sacn_send(0, [1], {}).error,
    noise: artnet_parse("00010203").error,
    cut: artnet_parse("4172742d4e6574000050000e00000000020000").error,
}

route GET /poll {
    let to = env("ARTNET_POLL_TO", "2.255.255.255")
    let nodes = artnet_poll(to, { wait_ms: 400 })?
    { found: len(nodes), nodes: nodes | map((n) => [n.short_name, n.long_name, n.ip, n.outputs, n.mac, n.style]) }
}

route GET /sacn {
    let opts = { host: SACN, source: "Stage left", priority: 150, cid: "6ba7b810-9dad-11d1-80b4-00c04fd430c8" }
    let a = artnet_sacn_send(7, [1, 2, 3], opts)?
    let b = artnet_sacn_send(7, [4, 5, 6], opts)?
    let c = artnet_sacn_send(7, [0, 0, 0], { ...opts, terminate: true })?
    {
        sequences: [a.sequence, b.sequence, c.sequence],
        bytes: a.bytes,
        multicast: artnet_sacn_multicast(7)?,
        high: artnet_sacn_multicast(300)?,
    }
}

// Our own packets, read back: the listener gets them on a port of its own.
route GET /loop {
    artnet_send(`127.0.0.1:${LISTEN}`, "1:2:3", [9, 8, 7, 6, 5])?
    artnet_sacn_send(44, [1, 2], { host: `127.0.0.1:${LISTEN}`, source: "Loop" })?
    let got = artnet_receive("mine", 10, 500)?
    let more = len(got) < 2 ? artnet_receive("mine", 10, 500)? : []
    let all = got + more
    { ops: all | map((f) => [f.op, f.universe]), dmx: all[0].channels, name: all[0].name, source: all[1].source }
}

// A node of our own answering, built and read back.
route GET /reply {
    let p = artnet_poll_reply({ ip: "2.0.0.99", short_name: "Quillo", long_name: "A node written in Quillo", report: "#0001 [0000] ok", universe: "0:1:3", mac: "02:00:00:00:00:99" })?
    { size: len(p), read: artnet_parse(p)? }
}
