module namespace c = 'urn:nubisware:keycloak:clients';

declare variable $c:keycloak-url := 'http://localhost:8080';
declare variable $c:token-url := '/auth/realms/master/protocol/openid-connect/token';
declare variable $c:clients-url := '/auth/admin/realms/test/clients';


declare function c:get-token() {
  let $url := $c:keycloak-url || $c:token-url
  
  let $form-params := map {
    'grant_type': 'password',
    'client_id': 'admin-cli',
    'username': 'admin',
    'password': 'admin'
  }
  
  let $body := substring(web:create-url('', $form-params), 2)
  
  let $http-req := 
    <http:request method="GET">
      <http:body media-type="application/x-www-form-urlencoded"/>
    </http:request>
    
  let $token := http:send-request($http-req, $url, $body)[2]//access__token/data()
  return $token
};


declare function c:create-client($params) {
  let $client-def := ``[
    {
      "clientId": "`{$params?clientId}`",
      "baseUrl": "`{$params?baseUrl}`",
      "enabled": true,
      "clientAuthenticatorType": "client-secret",
      "redirectUris": [
          "`{$params?redirectUri}`"
      ],
      "webOrigins": [
          "/*"
      ],
      "standardFlowEnabled": true,
      "directAccessGrantsEnabled": true,
      "publicClient": true,
      "protocol": "openid-connect",
      "attributes": {
          "login_theme": "`{$params?login_theme}`"
      },
      "fullScopeAllowed": true
    }
  ]``
  
  let $token := c:get-token()
  let $url := $c:keycloak-url || $c:clients-url

  let $http-req := 
    <http:request method="POST">
      <http:header name="Authorization" value="Bearer {$token}"/>
      <http:body media-type="application/json"/>
    </http:request>
  
  let $resp := http:send-request($http-req, $url, $client-def)
  
  return $params?clientId || ' : ' || $resp[1]/@status/data() || ' ' || $resp[1]/@message/data()
};


declare function c:delete-client($clientId) {
  let $token := c:get-token()
  let $url := $c:keycloak-url || $c:clients-url
  
  let $geturl := web:create-url($url, map { "clientId" : $clientId })
  let $http-req := 
    <http:request method="GET">
      <http:header name="Authorization" value="Bearer {$token}"/>
    </http:request>
  
  let $resp := http:send-request($http-req, $geturl)
  let $id := $resp[2]/json/_[clientId=$clientId]/id/data()

  return if ($id) then
    let $delurl := $url || '/' || $id
    let $http-req := 
      <http:request method="DELETE">
        <http:header name="Authorization" value="Bearer {$token}"/>
      </http:request>
    
    let $resp := http:send-request($http-req, $delurl)
    return $clientId || ' : ' || $resp[1]/@status/data() || ' ' || $resp[1]/@message/data()
};