" ___vital___
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
" Do not mofidify the code nor insert new lines before '" ___vital___'
function! s:_SID() abort
  return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
endfunction
execute join(['function! vital#_plantuml_previewer#System#Process#import() abort', printf("return map({'_vital_depends': '', 'execute': '', 'register': '', '_vital_loaded': ''}, \"vital#_plantuml_previewer#function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
delfunction s:_SID
" ___vital___
let s:save_cpoptions = &cpoptions
set cpoptions&vim

let s:registry = {}
let s:priority = []

function! s:_vital_loaded(V) abort
  let s:V = a:V
  let s:Prelude = a:V.import('Prelude')
  let s:String = a:V.import('Data.String')
  call s:register('System.Process.Vimproc')
  call s:register('System.Process.System')
endfunction

function! s:_vital_depends() abort
  return [
        \ 'Prelude',
        \ 'Data.String',
        \ 'System.Process.System',
        \ 'System.Process.Vimproc',
        \]
endfunction

function! s:_throw(msg) abort
  throw printf('vital: System.Process: %s', a:msg)
endfunction

function! s:register(name) abort
  let client = s:V.import(a:name)
  if client.is_available()
    let s:registry[a:name] = client
    call add(s:priority, a:name)
  endif
endfunction

function! s:_execute(args, options) abort
  for name_or_client in a:options.clients
    let client = s:Prelude.is_string(name_or_client)
          \ ? s:registry[name_or_client]
          \ : name_or_client
    if !client.is_supported(a:options)
      continue
    endif
    return client.execute(a:args, a:options)
  endfor
  call s:_throw(printf(
        \ 'None of client support options : %s',
        \ string(a:options),
        \))
endfunction

" execute({args}[, {options}])
function! s:execute(args, ...) abort
  let options = extend({
        \ 'clients': s:priority,
        \ 'input': 0,
        \ 'timeout': 0,
        \ 'background': 0,
        \ 'encode_input': 1,
        \ 'encode_output': 1,
        \ 'split_output': 1,
        \ 'debug': &verbose,
        \}, get(a:000, 0, {}))
  if s:Prelude.is_string(options.input) && !empty(options.encode_input)
    let encoding = s:Prelude.is_string(options.encode_input)
          \ ? options.encode_input
          \ : &encoding
    let options.input = s:String.iconv(options.input, encoding, 'char')
  endif
  let result = s:_execute(a:args, options)
  if s:Prelude.is_string(result.output) && !empty(options.encode_output)
    let encoding = s:Prelude.is_string(options.encode_output)
          \ ? options.encode_output
          \ : &encoding
    let result.output = s:String.iconv(result.output, 'char', encoding)
  endif
  if options.split_output
    let result.content = s:String.split_posix_text(result.output)
  endif
  let result.success = result.status == 0
  let result.args = a:args
  let result.options = options
  return result
endfunction

let &cpoptions = s:save_cpoptions
unlet s:save_cpoptions