// A card terminal's link to its acquirer: purchases sent as ISO 8583 0200 messages and the 0210
// answers read (approved, and declined for insufficient funds), a network echo test (0800), and,
// without a network, the same purchase packed in BCD, unpacked again, and explained for a log
// with the card number masked.
//
//   ISO8583_HOST=acquirer.test:5000 quillo run iso8583.qwe      then open http://localhost:8080/purchase
//
// Needs an authorization host at ISO8583_HOST that takes the 1987 fields in ASCII with a binary
// bitmap, each message after a 2-byte length (a test host or simulator; never real cards).

use "iso8583.qwer"

let HOST = env("ISO8583_HOST", "127.0.0.1:5000")

fn purchase(stan, cents) = {
    mti: "0200",
    "2": "4111111111111111",
    "3": "000000",
    "4": cents,
    "7": "1030101500",
    "11": stan,
    "12": "101500",
    "13": "1030",
    "14": "2812",
    "22": "051",
    "25": "00",
    "41": "TERM0042",
    "42": "QUILLO-SHOP-01",
    "49": "978",
}

route GET /purchase {
    let r = iso8583_send(HOST, purchase("000101", 2550), "ascii", { timeout_ms: 5000 })?
    { mti: r.mti, approved: r.explain.approved, response: r.explain.response, code: r["39"], auth_code: r["38"], stan: r["11"] }
}

route GET /declined {
    let r = iso8583_send(HOST, purchase("000102", 250000), "ascii", { timeout_ms: 5000 })?
    { mti: r.mti, approved: r.explain.approved, response: r.explain.response, code: r["39"] }
}

route GET /echo {
    let r = iso8583_send(HOST, { mti: "0800", "7": "1030101500", "11": "000103", "70": "301" }, "ascii", { timeout_ms: 5000 })?
    { mti: r.mti, code: r["39"], meaning: iso8583_mti(r.mti) }
}

route GET /offline {
    let msg = purchase("000104", 1999)
    let packed = iso8583_pack(msg, "bcd")?
    let back = iso8583_unpack(packed, "bcd")?
    // A host's own field 48: up to 50 characters after a 3-digit length.
    let spec = { base: "ascii", fields: { "48": { name: "Loyalty number", type: "ans", max: 50, prefix: 3 } } }
    {
        bcd_hex: packed,
        round_trip: back["4"] == "000000001999" && back["2"] == "4111111111111111",
        bitmap: back.bitmap,
        custom: iso8583_pack({ mti: "0100", "3": "000000", "48": "LOY-77" }, spec)?,
        too_long: iso8583_pack({ mti: "0200", "3": "1234567" }, "ascii").error,
        log: iso8583_explain(back, "bcd")?,
    }
}
