ruleset io.picolabs.plan.webhook {
  meta {
    name "webhooks"
    use module io.picolabs.plan.apps alias app
    use module io.picolabs.wrangler alias wrangler
    shares webhook
  }
  global {
    styles = <<<style type="text/css">
table {
  border: 1px solid black;
  border-collapse: collapse;
}
td, th {
  border: 1px solid black;
  padding: 5px;
}
</style>
>>
    webhook = function(_headers){
      identifierRE = "[A-Za-z][A-Za-z0-9_]*"
      app:html_page("manage webhooks", styles,
<<
<h1>Manage Webhooks</h1>
<form action="#{app:event_url(meta:rid,"new_webhook")}">
<table>
<tr>
<th>Event domain</th>
<th>Event type</th>
<th>URL</th>
<th>del</th>
</tr>
#{ent:webhooks.values().map(function(w){
  uri = w.get("uri")
  del_url = app:event_url(meta:rid,"webhook_not_needed")
          + "?event_domain=" + w.get("domain")
          + "&event_type=" + w.get("type")
  <<<tr>
<td>#{w.get("domain")}</td>
<td>#{w.get("type")}</td>
<td><a href="#{uri}" target="_blank" title="#{uri}">webhook</a></td>
<td><a href="#{del_url}">del</a></td>
</tr>
>>}).join("")}
<tr>
<td><input name="event_domain" required pattern="#{identifierRE}" title="identifier"></td>
<td><input name="event_type" required pattern="#{identifierRE}" title="identifier"></td>
<td colspan="2"><button type="submit">Add</button></td>
</tr>
</table>
</form>
>>, _headers)
    }
  }
  rule initialize {
    select when io_picolabs_plan_webhook factory_reset
      where ent:webhooks.isnull()
    fired {
      ent:webhooks := {}
    }
  }
  rule addNewWebhook {
    select when io_picolabs_plan_webhook new_webhook
      event_domain re#([A-Za-z][A-Za-z0-9_]*)#
      event_type   re#([A-Za-z][A-Za-z0-9_]*)#
      setting(event_domain,event_type)
    pre {
      event_designation = event_domain + ":" + event_type
      channel_tags = ["webhook",event_designation]
      already_assigned = ent:webhooks >< event_designation
    }
    if not already_assigned then
      wrangler:createChannel(
        channel_tags,
        {"allow":[{"domain":event_domain,"name":event_type}],"deny":[]},
        {"allow":[],"deny":[{"rid":"*","name":"*"}]}
      ) setting(chan)
    fired {
      ent:webhooks{event_designation} := {
        "domain":event_domain,
        "type":event_type,
        "uri":meta:host+"/sky/event/"+chan.get("id")+"/none/"+event_domain+"/"+event_type
      }
    }
  }
  rule removeWebhook {
    select when io_picolabs_plan_webhook webhook_not_needed
      event_domain re#([A-Za-z][A-Za-z0-9_]*)#
      event_type   re#([A-Za-z][A-Za-z0-9_]*)#
      setting(event_domain,event_type)
    pre {
      event_designation = event_domain + ":" + event_type
      webhook = ent:webhooks.get(event_designation)
      eciRE = re#/sky/event/([^/]*)/#
      eci = webhook.get("uri").extract(eciRE).head()
    }
    if eci then wrangler:deleteChannel(eci)
    fired {
      clear ent:webhooks{event_designation}
    }
  }
  rule refresh {
    select when io_picolabs_plan_webhook new_webhook
             or io_picolabs_plan_webhook webhook_not_needed
    pre {
      home_page = app:query_url(meta:rid,"webhook.html")
    }
    send_directive("_redirect",{"url":home_page})
  }
}