// What goes on an NFC tag: a link with its short prefix code, a poster with titles in two
// languages and an app to open, a contact card, and what a phone reads back; chunked records
// joined, and a damaged tag refused. No reader needed: a message is bytes, and the hex here can
// be written with any tag app.
//
//   quillo run nfc_ndef.qwe      then open http://localhost:8080/link, /poster, /chunks and /damaged

use "nfc_ndef.qwer"

route GET /link {
    let msg = ndef_build([{ type: "uri", uri: "https://www.example.com/menu" }])?
    {
        hex: msg,
        code: ndef_uri_prefix("https://www.example.com/menu"),
        phone: ndef_uri_prefix("tel:+15551234"),
        unknown_scheme: ndef_uri_prefix("geo:37.78,-122.40"),
        back: ndef_parse(msg)?.records,
    }
}

route GET /text {
    let msg = ndef_build([{ type: "text", text: "Hallo Welt", lang: "de" }, { type: "text", text: "こんにちは", lang: "ja", encoding: "utf-16" }])?
    { hex: msg, back: ndef_parse(msg)?.records }
}

// A poster on a shop window: a link, two titles, the app it should open, and a card.
route GET /poster {
    let msg = ndef_build([
        { type: "smart_poster", uri: "https://example.com/sale", title: { en: "Winter sale", fr: "Soldes d'hiver" }, action: "open", size: 2048, content_type: "text/html" },
        { type: "android_app", package: "com.example.shop" },
        { type: "mime", mime: "text/vcard", text: "BEGIN:VCARD\nVERSION:3.0\nFN:Ada\nEND:VCARD\n", id: "card" },
        { type: "external", domain_type: "example.com:stock", hex: "01ff" },
    ])?
    let back = ndef_parse(msg)?
    { count: back.count, records: back.records, headers: ndef_inspect(msg)? | map((h) => [h.tnf, h.type, h.mb, h.me]) }
}

// A large payload gets a long record by itself, and may come in chunks.
route GET /chunks {
    let body = repeat("0123456789", 40)
    let whole = ndef_build([{ type: "mime", mime: "text/plain", text: body }])?
    let parts = ndef_build_chunked([{ type: "mime", mime: "text/plain", text: body }, { type: "uri", uri: "tel:112" }], 150)?
    let back = ndef_parse(parts)?
    {
        short_record: ndef_inspect(whole)?[0].sr,
        chunks: ndef_inspect(parts)? | map((h) => [h.tnf, h.cf, h.payload_length]),
        joined: len(back.records[0].text),
        same: back.records[0].text == body,
        chunked: back.chunked,
        after: back.records[1].uri,
    }
}

// As it sits on a Type 2 tag: lock TLV, the message, terminator.
route GET /tag {
    let msg = ndef_build([{ type: "uri", uri: "https://nfc-forum.org" }])?
    let wrapped = ndef_tlv_wrap(msg)?
    let memory = "0103a00c340000" + wrapped + "0000"
    { wrapped: wrapped, found: ndef_tlv_unwrap(memory)? == msg, blank: ndef_tlv_unwrap("0000fe0000")?, cut: ndef_tlv_unwrap("03ff0100").error }
}

route GET /damaged = {
    cut: ndef_parse("d1010f55").error,
    no_end: ndef_parse("9101015500").error,
    not_first: ndef_parse("51010155").error,
    reserved_prefix: ndef_parse("d101025530ff").error,
    lone_chunk: ndef_parse("b6000101").error,
    unended_chunks: ndef_parse("b5000161" + "560001").error,
    bad_action: ndef_build([{ type: "smart_poster", uri: "x:y", action: "burn" }]).error,
    bad_kind: ndef_build([{ type: "wifi" }]).error,
}
