// Search through Algolia: objects saved and waited on, searches with facets, partial updates, an
// index browsed to the end, a secured key for one visitor, and hosts that fail passed over.
//
//   ALGOLIA_APP_ID=... ALGOLIA_API_KEY=... ALGOLIA_SEARCH_KEY=... quillo run algolia.qwe
//   then open /write, /search, /partial, /browse, /keys, /hosts and /failures
//
// ALGOLIA_HOSTS, comma-separated, replaces Algolia's hosts, as for a test server. Writes need a key
// with that right, and a browser only ever gets a secured key made from a search-only one.

use "algolia.qwer"

route GET /write {
    let one = algolia_save("products", { objectID: "mug-1", name: "Blue mug", brand: "Acme & Co", price: 12, tags: ["kitchen"], stock: 5 })?
    let auto = algolia_save("products", { name: "No id yet", brand: "Other", price: 3 })?
    let many = algolia_save_many("products", map(range(0, 2500), (i) => { objectID: `item-${i}`, name: `Item ${i}`, brand: if i % 2 == 0 { "Acme & Co" } else { "Globex" }, price: i % 50 }))?
    {
        waited: algolia_wait("products", one.taskID, 5000)?,
        all_in: algolia_wait("products", many.tasks[len(many.tasks) - 1], 5000)?,
        tasks: len(many.tasks), saved: many.saved,
        made_id: auto.objectID != null,
        read: algolia_get("products", "mug-1", ["name", "price"])?,
        not_map: algolia_save("products", [1]).error,
        slow: algolia_wait("products", 9999999, 150).error,
    }
}

route GET /search {
    let r = algolia_search("products", "item", { filters: algolia_filter("brand", "Acme & Co")?, facets: ["brand"], hitsPerPage: 5, page: 1 })?
    {
        hits: len(r.hits), total: r.nbHits, page: r.page, pages: r.nbPages, facets: r.facets,
        stats: r.facets_stats.price,
        filters: [algolia_filter("brand", "A \"B\"")?, algolia_filter("price", 10)?, algolia_filter("visible", true)?],
        facet_search: algolia_facet_search("products", "brand", "ac", {})?,
        not_searchable: algolia_facet_search("products", "price", "1", {}).error,
    }
}

route GET /partial {
    algolia_save("products", { objectID: "mug-2", name: "Red mug", stock: 5, tags: ["kitchen"] })?
    algolia_partial("products", "mug-2", { stock: algolia_op("Increment", 3)?, tags: algolia_op("AddUnique", "sale")?, name: "Red mug, large" }, false)?
    let many = algolia_partial_many("products", [{ objectID: "mug-2", stock: 1 }, { objectID: "missing", stock: 1 }], false)?
    let read = algolia_get("products", "mug-2", [])?
    let del = algolia_delete("products", "mug-2")?
    {
        name: read.name, stock: read.stock, tags: read.tags, many: many.saved,
        kept_out: algolia_get("products", "missing", []).error,
        no_id: algolia_partial_many("products", [{ stock: 1 }], false).error,
        bad_op: algolia_op("Multiply", 2).error,
        deleted: del.taskID != null,
        made: algolia_partial("products", "fresh", { stock: 1 }, true)?.objectID,
        not_made: algolia_partial("products", "ghost", { stock: 1 }, false)?.objectID,
        ghost: algolia_get("products", "ghost", []).error,
    }
}

route GET /browse {
    let all = algolia_browse("catalog", {}, 0)?
    {
        all: len(all), capped: len(algolia_browse("catalog", {}, 1500)?), past_search: algolia_search("catalog", "", { page: 20, hitsPerPage: 100 })?.hits,
        settings: algolia_settings_set("catalog", { attributesForFaceting: ["searchable(brand)"], customRanking: ["desc(sales)"] })?.taskID != null,
        read: algolia_settings("catalog")?.customRanking,
    }
}

route GET /keys {
    let key = algolia_secured_key("parent-search-key", { filters: "user_id:42 AND visible:true", validUntil: 1893456000, restrictIndices: ["orders", "invoices"] })?
    let back = algolia_secured_key_read(key)?
    {
        key: key,
        restrictions: back.restrictions,
        left: back.seconds_left > 0,
        none: algolia_secured_key("p", {}).error,
        bad_time: algolia_secured_key("p", { validUntil: "soon" }).error,
        junk: algolia_secured_key_read("not base64!").error,
    }
}

route GET /hosts = {
    down: map(algolia_hosts_down(), (h) => slice(h, 0, 7)),
    still_works: algolia_settings("products")? != null,
}

route GET /failures = {
    missing: algolia_get("products", "nosuch", []).error,
    bad_key: algolia_get("forbidden", "x", []).error,
    bad_query: algolia_search("products", "x", { filters: "price>" }).error,
    no_index: algolia_search("", "x", {}).error,
}
