# Python parser for Subversion skels

import string, re
from types import *

def parse(s):
  if s[0] != '(' and s[-1] != ')':
    raise ValueError("Improperly bounded skel: '%s'" % s)
  wholeskel = s
  s = s[1:-1].lstrip()
  prev_accums = []
  accum = []
  while 1:
    if len(s) == 0:
      return accum
    if s[0] in string.digits:
      split_tuple = s.split(' ',1)
      count = int(split_tuple[0])
      if len(split_tuple) > 1:
        s = split_tuple[1]
      else:
        s = ""
      accum.append(s[:count])
      s = s[count:].lstrip()
      continue
    if s[0] in string.ascii_letters:
      i = 0
      while (s[i] not in ' ()'):
        i += 1
        if i == len(s):
          break
      accum.append(s[:i])
      s = s[i:].lstrip()
      continue
    if s[0] == '(':
      new_accum = []
      accum.append(new_accum)
      prev_accums.append(accum)
      accum = new_accum
      s = s[1:].lstrip()
      continue
    if s[0] == ')':
      accum = prev_accums.pop()
      s = s[1:].lstrip()
      continue
    if s[0] == ' ':
      s = str.lstrip(' ')
      continue
    raise ValueError("Unexpected contents in skel: '%s'\n'%s'" % (s, wholeskel))


_ok_implicit = re.compile(r'^[A-Za-z]([^\(\) \r\n\t\f]*)$')
def unparse(struc):
  accum = []
  for ent in struc:
    if type(ent) == StringType:
      if len(ent) > 0 and _ok_implicit.match(ent[0]):
        accum.append(ent)
      else:
        accum.append(str(len(ent)))
        accum.append(ent)
    else:
      accum.append(unparse(ent))
  return "("+" ".join(accum)+")"


class Rev:
  def __init__(self, skelstring="(revision null)"):
    sk = parse(skelstring)
    if len(sk) == 2 and sk[0] == "revision" and type(sk[1]) == StringType:
      self.txn = sk[1]
    else:
      raise ValueError("Invalid revision skel: %s" % skelstring)

  def unparse(self):
    return unparse( ("revision", self.txn) )


class Change:
  def __init__(self, skelstring="(change null null null 0  0 )"):
    sk = parse(skelstring)
    if len(sk) == 6 and sk[0] == "change" and type(sk[1]) == type(sk[2]) \
        == type(sk[3]) == type(sk[4]) == type(sk[5]) == StringType:
          self.path = sk[1]
          self.node = sk[2]
          self.kind = sk[3]
          self.textmod = sk[4]
          self.propmod = sk[5]
    else:
      raise ValueError("Invalid change skel: %s" % skelstring)

  def unparse(self):
    return unparse( ("change", self.path, self.node, self.kind,
                     self.textmod and "1" or "", self.propmod and "1" or "") )


class Copy:
  def __init__(self, skelstring="(copy null null null)"):
    sk = parse(skelstring)
    if len(sk) == 4 and sk[0] in ("copy", "soft-copy") and type(sk[1]) \
        == type(sk[2]) == type(sk[3]) == StringType:
          self.kind = sk[0]
          self.srcpath = sk[1]
          self.srctxn = sk[2]
          self.destnode = sk[3]
    else:
      raise ValueError("Invalid copy skel: %s" % skelstring)

  def unparse(self):
    return unparse( (self.kind, self.srcpath, self.srctxn, self.destnode) )


class Node:
  def __init__(self,skelstring="((file null null 1 0) null null)"):
    sk = parse(skelstring)
    if (len(sk) == 3 or (len(sk) == 4 and type(sk[3]) == StringType)) \
        and type(sk[0]) == ListType and type(sk[1]) == StringType \
        and type(sk[2]) == StringType and sk[0][0] in ("file", "dir") \
        and type(sk[0][1]) == type(sk[0][2]) == type(sk[0][3]) == StringType:
          self.kind = sk[0][0]
          self.createpath = sk[0][1]
          self.prednode = sk[0][2]
          self.predcount = int(sk[0][3])
          self.proprep = sk[1]
          self.datarep = sk[2]
          if len(sk) > 3:
            self.editrep = sk[3]
          else:
            self.editrep = None
    else:
      raise ValueError("Invalid node skel: %s" % skelstring)

  def unparse(self):
    structure = [ (self.kind, self.createpath, self.prednode,
        str(self.predcount)), self.proprep, self.datarep ]
    if self.editrep:
      structure.append(self.editrep)
    return unparse( structure )


class Txn:
  def __init__(self,skelstring="(transaction null null () ())"):
    sk = parse(skelstring)
    if len(sk) == 5 and sk[0] in ("transaction", "committed", "dead") \
        and type(sk[1]) == type(sk[2]) == StringType \
        and type(sk[3]) == type(sk[4]) == ListType and len(sk[3]) % 2 == 0:
          self.kind = sk[0]
          self.rootnode = sk[1]
          if self.kind == "committed":
            self.rev = sk[2]
          else:
            self.basenode = sk[2]
          self.proplist = sk[3]
          self.copies = sk[4]
    else:
      raise ValueError("Invalid transaction skel: %s" % skelstring)

  def unparse(self):
    if self.kind == "committed":
      base_item = self.rev
    else:
      base_item = self.basenode
    return unparse( (self.kind, self.rootnode, base_item, self.proplist,
      self.copies) )


class SvnDiffWindow:
  def __init__(self, skelstructure):
    self.offset = skelstructure[0]
    self.str = skelstructure[1][0][2]
    self.size = skelstructure[1][1]
    self.vs_rep = skelstructure[1][2]
    #self.rep_offset = skelstructure[1][3]
    

class Rep:
  def __init__(self, skelstring="((fulltext 0  (md5 16 \0\0\0\0\0\0\0\0" \
          "\0\0\0\0\0\0\0\0)) null)"):
    sk = parse(skelstring)
    if type(sk[0]) == ListType and len(sk[0]) == 3 \
        and type(sk[0][1]) == StringType \
        and type(sk[0][2]) == ListType and len(sk[0][2]) == 2 \
        and type(sk[0][2][0]) == type(sk[0][2][1]) == StringType:
          self.kind = sk[0][0]
          self.txn = sk[0][1]
          self.cksumtype = sk[0][2][0]
          self.cksum = sk[0][2][1]
          if len(sk) == 2 and sk[0][0] == "fulltext":
            self.str = sk[1]
          elif len(sk) >= 2 and sk[0][0] == "delta":
            self.windows = map(SvnDiffWindow, sk[1:])
    else:
      raise ValueError("Invalid representation skel: %s" % repr(skelstring))

  def unparse(self):
    structure = [ [self.kind, self.txn, [self.cksumtype, self.cksum] ] ]
    if self.kind == "fulltext":
      structure.append(self.str)
    elif self.kind == "delta":
      structure.extend(self.windows)
    return unparse( structure )

