#!/usr/bin/python3

'''
virsh-pyquery, version 0.1

Copyright 2012 Jan ONDREJ (SAL) <ondrejj(at)salstar.sk>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA.

Syntax:
  virsh-pyquery --guest NAME PARAMETERS -- PARAMETERS -- ...

PARAMETERS syntax:
  "jquery selector" [--add element --opts atribute=value \\
                    |--delete \\
                    |--remove attribute [--remove attribute ...] \\
                    |[--update] --opts attribute=value]

Examples:
  --guest NAME os --add bios --opts useserial=yes
  --guest NAME "devices disk driver" --update --opts cache=none
  --guest NAME "disk driver" --remove cache --remove type
  --guest NAME "os boot[dev=cdrom]" --delete

For more information about jquery selectors see:
  http://api.jquery.com/category/selectors/
'''

from pyquery import PyQuery as pq
import sys, os, getopt

def guests(opts):
    for key, value in opts:
      if key=='--guest' or key=='-G':
        yield value

def split_mm(args):
    ret = []
    for arg in args:
      if arg=="--":
        yield ret
        ret = []
      else:
        ret.append(arg)
    if ret:
      yield ret

def apply_opts(e, opts):
    for key, value in opts:
      if key=='--opts' or key=='-o':
        k, v = value.split("=", 1)
        e.attr(k, v)
    return e

try:
  opts, args = getopt.gnu_getopt(sys.argv[1:3], 'G:h', ['guest=', 'help'])
  params = dict(opts)
  if '--help' in params or '-h' in params:
    print(__doc__)
    sys.exit(0)
except getopt.GetoptError as err:
  print("Error:", str(err))
  sys.exit(1)

for guest in guests(opts):
  source = os.popen('virsh dumpxml %s' % guest).read()
  q = pq(source, parser="xml")

  for argv in split_mm(sys.argv[3:]):
    try:
      opts, args = getopt.gnu_getopt(argv,
        'a:dr:uo:',
        ['add=', 'delete', 'remove=', 'update', 'opts=']
      )
      params = dict(opts)
    except getopt.GetoptError as err:
      print("Error:", str(err))
      sys.exit(1)

    query_args = ' '.join(args)
    elements = q(query_args)
    if '--add' in params or '-a' in params:
      if '-a' in params:
        e = pq("<%s/>\n" % params.get('-a'))
      elif '--add' in params:
        e = pq("<%s/>\n" % params.get('--add'))
      apply_opts(e, opts).appendTo(elements)
    elif '--delete' in params or '-d' in params:
      q.remove(query_args)
    elif '--remove' in params or '-r' in params:
      for key, value in opts:
        if key=='-r' or key=='--remove':
          elements.attr(value, None)
    else:
      # '--update' in params or '-u' in params:
      apply_opts(elements, opts)

  #print(str(q).strip())
  f = os.popen('EDITOR="cat >" virsh edit %s' % guest, 'w')
  f.write(str(q))
  f.close()
