# coding: utf8
# subx2y.py
# Convert subtitles in old XML format to new YAML format.
# 12/16/2014 jichi

if __name__ == '__main__':
  import initrc
  #initrc.chcwd()
  initrc.initenv()

  import os
  title = os.path.basename(__file__)
  initrc.settitle(title)

import os, re, sys
from datetime import datetime
from sakurakit import skyaml
from lxml import etree
#from sakurakit.skdebug import dprint, dwarn
#from sakurakit.skprof import SkProfiler
import initdefs

MAX_TEXT_LENGTH = 255
MAX_SUB_LENGTH = 384
#MAX_NAME_LENGTH = 64

def sametext(text): return text
normalizetext = sametext
#def inverttext(text): return re.sub(u"(.*)(【.*】)", r'\2\1', text) # 「バッチリなのよさ」【蒔菜】
#normalizetext = inverttext

CONTEXT_SEP = "||"
def convert(userId=0, type='', text='', language='', context="", contextSize=0, comment='', updateComment='', disabled=False, **kwargs):
  """
  @return  dict or None
  """
  if not disabled and text and context and type == 'subtitle':
    ret = {}
    if language:
      ret['subLang'] = language
    if contextSize > 1:
      t = context.split(CONTEXT_SEP)[-1]
    else:
      t = context
    ret['text'] = normalizetext(t)
    ret['sub'] = text
    #if userId:
    #  ret['userId'] = userId
    c = comment or updateComment
    if c:
      ret['comment'] = c

    t = ret['text']
    if len(t) > MAX_TEXT_LENGTH:
      print "text too long (%s):" % len(t), t

    t = ret['sub']
    if len(t) > MAX_SUB_LENGTH:
      print "sub too long (%s):" % len(t), t
    return ret

# Fields
# - userId
# - subLang
# - sub
# - text
# - comment
def readxml(xmlfile): # unicode -> [Subtitle]
  print "read xml:", xmlfile
  ret = []
  try:
    context = etree.iterparse(xmlfile, events=('start','end'))
    path = 0
    for event, elem in context:
      if event == 'start':
        path += 1
        if path == 3: # grimoire/comments/comment
          kw = {
            'id': int(elem.get('id')),
            'type': elem.get('type'),
            'disabled': elem.get('disabled') == 'true',
            'locked': elem.get('locked') == 'true',
          }
      else:
        path -= 1
        if path == 3: # grimoire/comments/comment
          tag = elem.tag
          text = elem.text
          if tag in ('language', 'text', 'comment', 'updateComment'):
            kw[tag] = text or ''
          #elif tag in ('gameId', 'userId', 'timestamp', 'updateUserId', 'updateTimestamp'):
          elif tag.endswith('Id') or tag.endswith('Hash') or tag.endswith('Count') or tag.endswith('imestamp'):
            kw[tag] = int(text)
          elif tag == 'context':
            kw['context'] = text or ''
            kw['hash'] = long(elem.get('hash'))
            kw['contextSize'] = int(elem.get('size'))

        elif path == 2: # grimoire/comments
          #if not kw.get('userHash'):
          #  kw['userHash'] = kw['userId']
          s = convert(**kw)
          if s:
            ret.append(s)

    print "pass"
    return ret

  except etree.ParseError, e:
    print "xml parse error", e.args
  except (TypeError, ValueError, AttributeError), e:
    print "xml malformat", e.args
  except Exception, e:
    print e
  print "failed"

def writeyaml(path, subs, textLang='ja', subLang=''):
  """
  @param  path  unicode
  @param  subs  [dict]
  @param* textLang  str
  @param* subLang  str
  @return  bool
  """
  print "write yaml:", path
  options = {}
  if textLang:
    options['textLang'] = textLang
  if subLang:
    options['subLang'] = subLang
  subs.insert(0, options)
  try:
    with open(path, 'w') as f:
      now = datetime.now()
      comment = "# Generated by VNR's subx2y on %s\n" % now.strftime("%Y-%m-%d %H:%M")
      f.write(comment)
      skyaml.dump(subs, f)
    print "pass"
    return True
  except Exception, e:
    print e
  print "failed"
  return False

def extractSubLang(subs):
  """
  @param  subs  [kw[
  @return  str lang or None
  """
  lang = ''
  for s in subs:
    v = s.get('subLang')
    if not v:
      return
    if not lang:
      lang = v
    elif v != lang:
      return
  return lang

def x2y(path):
  """
  @param  path  unicode
  @return  bool
  """
  base, suffix = os.path.splitext(path)
  if suffix.lower() == '.xml':
    output = base + '.yaml'
  else:
    output = path + '.yaml'
  l = readxml(path)
  if not l:
    return False
  subLang = extractSubLang(l)
  if subLang:
    for s in l:
      try: del s['subLang']
      except KeyError: pass
  return writeyaml(output, l, subLang=subLang)

## Main ##

def usage():
  cmd = os.path.basename(sys.argv[0])
  VERSION = 1418779662
  print """\
usage: %s xmlfile1 [xmlfile2] ...
version: %s
Convert subtitles in old XML format to new YAML format.""" % (cmd, VERSION)

def main(argv):
  """
  @param  argv  [unicode]
  @return  int  error file count
  """
  if len(argv) == 0 or argv[0] in initdefs.HELP_FLAGS:
    usage()
    return 0
  #dprint("enter")

  errorCount = 0
  for i,path in enumerate(argv):
    if i:
      print
    ok = x2y(path)
    if not ok:
      errorCount += 1
  return errorCount

if __name__ == '__main__':
  ret = main(sys.argv[1:])
  sys.exit(ret)

# EOF
