#! /usr/bin/python

import socket
import subprocess
import errno
import sys
import os
import json
import argparse

class ArgumentParser(argparse.ArgumentParser):    
  def _get_action_from_name(self, name):
    """Given a name, get the Action instance registered with this parser.
    If only it were made available in the ArgumentError object. It is 
    passed as it's first arg...
    """
    container = self._actions
    if name is None:
      return None
    for action in container:
      if '/'.join(action.option_strings) == name:
        return action
      elif action.metavar == name:
        return action
      elif action.dest == name:
       return action

  def has_dest(self, name):
    for a in self._actions:
      if a.dest == name:
        return True
    return False

  def error(self, message):
    exc = sys.exc_info()[1]
    if exc:
      exc.argument = self._get_action_from_name(exc.argument_name)
      raise exc
    super(ArgumentParser, self).error(message)

port = 7890

job_parser = ArgumentParser(description="Specify an export job")
job_parser.add_argument("input_swf", nargs="?", help="location of a .swf file to export")
job_parser.add_argument("-t", "--type", default=1, help="export type: 1=spritesheet, 3=skeletal", choices=[1,3])

cmd_parser = ArgumentParser(description="Export .swf files, either from the command line or piped from stdin", parents=[job_parser], conflict_handler="resolve")
cmd_parser.add_argument("-p", "--port", default=port, help="port to use for the wrapper server", type=int)

try:
  cmd_args = cmd_parser.parse_args()
except argparse.ArgumentError, exc:
  # only show cmd line errors for things *just* in the cmd_parser (we will parse other stuff later)
  if cmd_parser.has_dest(exc.argument.dest) and not job_parser.has_dest(exc.argument.dest):
    super(ArgumentParser, cmd_parser).error(exc.message)

s = socket.socket()
s.bind(("localhost", port))

args = [os.getcwd() + "/GraphicExport.exe"]
# args = [os.getcwd() + "/GraphicExport.app/GraphicExport.exe", str(port)]
g = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

s.settimeout(0.5)
s.listen(0)

conn = None
while conn is None and g.returncode is None:
  try:
    (conn, _) = s.accept()
  except socket.timeout, e:
      pass
  except e:
    print e
    s.close()
    g.wait()
    sys.exit(1)
  g.poll()

if conn:
  conn.setblocking(False)

  conn.send("EXPORT|" + "|".join(sys.argv[1:]) + "\0")

while g.returncode is None:
  try:
    d = conn.recv(4096)
    if len(d):
      sys.stdout.write(d)
      sys.stdout.flush()
  except socket.error, e:
    if e.args[0] == errno.EWOULDBLOCK or e.args[0] == errno.EAGAIN:
      pass
    else:
      print e
      conn.close()
      s.close()
      g.wait()
      sys.exit(1)
  g.poll()

if (conn):
  conn.close()
s.close()
