(:~
 : Single user.
 :
 : @author Christian Grün, BaseX Team, BSD License
 :)
module namespace dba = 'dba/users';

import module namespace config = 'dba/config' at '../lib/config.xqm';
import module namespace html = 'dba/html' at '../lib/html.xqm';

(:~ Top category :)
declare variable $dba:CAT := 'users';
(:~ Sub category :)
declare variable $dba:SUB := 'user';

(:~
 : Single user.
 : @param  $name     username
 : @param  $newname  new name
 : @param  $pw       password
 : @param  $perm     permission
 : @param  $error    error string
 : @param  $info     info string
 : @return page
 :)
declare
  %rest:GET
  %rest:path('/dba/user')
  %rest:query-param('name',    '{$name}')
  %rest:query-param('newname', '{$newname}')
  %rest:query-param('pw',      '{$pw}')
  %rest:query-param('perm',    '{$perm}')
  %rest:query-param('error',   '{$error}')
  %rest:query-param('info',    '{$info}')
  %output:method('html')
function dba:user(
  $name     as xs:string,
  $newname  as xs:string?,
  $pw       as xs:string?,
  $perm     as xs:string?,
  $error    as xs:string?,
  $info     as xs:string?
) as element(html) {
  let $user := user:list-details($name)
  let $admin := $name eq 'admin'
  return (
    <div class='panel'>
      <form method='post' autocomplete='off'>
        <h2>{
          html:link('Users', $dba:CAT), ' » ',
          $name, ' » ',
          html:button('user-update', 'Update')
        }</h2>
        <input type='hidden' name='name' value='{ $name }'/>
        {
          if ($admin) then <input type='hidden' name='newname' value='admin'/> else (
            html:field('Name:',
              <input type='text' name='newname' value='{ $newname otherwise $name }' autofocus=''/>)
          ),
          html:field('Password:', (
            <input type='password' name='pw' value='{ $pw }' autocomplete='new-password'/>,
            '&#xa0;',
            <span class='note'>…only changed if a new one is entered</span>
          )),
          if ($admin) then <input type='hidden' name='perm' value='admin'/> else (
            html:field('Permission:',
              <select name='perm' size='5'>{
                let $prm := $perm otherwise $user/@permission
                for $p in $config:PERMISSIONS
                return element option { if ($p = $prm) then attribute selected { }, $p }
              }</select>)
          ),
          html:field('Information:',
            <textarea name='info' id='editor' spellcheck='false'>{
              serialize(user:info($name), { 'indent': true() } )
            }</textarea>),
          html:js('loadCodeMirror("xml", true);')
        }
      </form>
    </div>,
    <div class='panel'>{
      if (not($admin)) {
        <_>
          <h3>Local Permissions</h3>
          <form method='post' autocomplete='off'>
            <input type='hidden' name='name' value='{ $name }' id='name'/>
            {
              let $headers := (
                { 'key': 'pattern', 'label': 'Pattern' },
                { 'key': 'permission', 'label': 'Local Permission' }
              )
              let $entries := $user/database ! {
                'pattern': @pattern,
                'permission': @permission
              }
              let $buttons := (
                html:button('pattern-add', 'Add…'),
                html:button('users/pattern-drop', 'Drop', ('CHECK', 'CONFIRM'))
              )
              return html:table($headers, $entries, $buttons)
            }
          </form>
          <div class='note'>
            A global permission can be overwritten by a local permission.<br/>
            Local permissions are applied to those databases that match<br/>
            a specified pattern. The pattern is based on the <a target='_blank'
              href='https://docs.basex.org/main/Commands#Glob_Syntax'>glob syntax</a>.<br/>
          </div>
        </_>/node()
      }
    }</div>
  ) => html:wrap({ 'header': ($dba:CAT, $name), 'info': $info, 'error': $error })
};
