(:~
 : jsonrpc
 : @author andy bunce
 :)
module namespace lsprpc = 'lsprpc';
import module namespace lsp-text = 'lsp-text' at "lsp-text.xqm";

(: map methods to functions :)
declare variable $lsprpc:methods:=map:merge((
  map{
  "initialize" : lsprpc:method-initialize#1,
  "initialized" : lsprpc:method-initialized#1,
  "workspace/didChangeConfiguration" :lsprpc:method-unknown#1
},
  $lsp-text:methods
));

(:~ return map if $msg is jsonrpc else empty :)
declare
function lsprpc:parse($msg as xs:string) 
as map(*)? 
{
  try {
    let $json:=parse-json($msg)
    return if($json?jsonrpc="2.0" and exists($json?method))
           then $json
           else ()
  } catch *{ 
    ()
  }
  
};

(:~ send replay to $json :)
declare
function lsprpc:reply($json as map(*)) 
as empty-sequence() {
  let $method := $json?method
  let $f :=$lsprpc:methods?($method)
  let $response := $f!.($json)
  return if(exists($response)) then ws:send($response=>trace("REPLY: "),ws:id())
};

(:~ canned initialize response :)
declare
function lsprpc:method-initialize($json as map(*)) 
as map(*)
{
{
  "jsonrpc": "2.0",
  "id": $json?id,
  "result": json:doc("capabilities.json",{"format":"w3"})
}
};

(:~ initialized response :)
declare
function lsprpc:method-initialized($json as map(*)) 
as empty-sequence()
{
  ws:set(ws:id(),"initialized", true())
};

(:~  unknown method response :)
declare
function lsprpc:method-unknown($json as map(*)) 
as map(*)?
{
 let $_:=trace($json?method,"unknown")
 return ()
};

