#!/usr/bin/env python

# setup the environment

import os, sys


# function to tidy python command lines

def python_tidy( line ):
  py = ""
  s = line.strip()+' '
  if ( s[0] == '%' ):
    return ''
  for i in range(len(line)):
    if ( line[i] != '_' ):
      break
  for j in range(len(line)):
    if ( j < i ):
      py += " "
    else:
      py += line[j]
  return py


# Test for environment variables

if not os.environ.has_key('CCP4'):
  raise RuntimeError, 'CCP4 not found'
if os.environ['CCP4_OPEN'] == 'NEW':
  os.environ['CCP4_OPEN'] = 'UNKNOWN'

# get the command input

cmds = sys.stdin.readlines()

# fetch the control parameters

inctrl = False
ctrl = ""
task = ""

for cmd in cmds:
  words = cmd.strip().split()
  if ( len(words) > 0 ):
    if words[0] == "%control":
      inctrl = True
    if words[0] == "%task":
      inctrl = False
  if ( inctrl ):
    ctrl += python_tidy( cmd )
  else:
    task += cmd

# class definition for container process

clsin = """
class Control:
  def __init__( self, tsktxt ):
    self.taskdict = {}
    lines = tsktxt.split( '\\n' )
    tasknm = ''
    taskprg = ''
    taskarg = ''
    taskcmd = ''
    for line in lines:
      words = line.split()
      if ( len(words) > 0 ):
        if ( words[0][0] == '%' ):
          if ( words[0] == '%task' ):
            if ( tasknm != '' ):
              self.taskdict[ tasknm ] = ( taskprg, taskarg, taskcmd )
            tasknm = ''
            taskprg = ''
            taskarg = ''
            taskcmd = ''
            if ( len(words) > 1 ): tasknm  = words[1].strip()
          if ( words[0] == '%program' ):
            if ( len(words) > 1 ): taskprg = words[1].strip()
          if ( words[0] == '%args' ):
            for i in range( 1, len(words) ):
              taskarg += words[i] + ' '
        else:
          taskcmd += line+'\\n'
    if ( tasknm != '' ):
      self.taskdict[ tasknm ] = ( taskprg, taskarg, taskcmd )

  def get_program( self, tsknm ):
    return self.taskdict[tsknm][0]
    
  def get_arguments( self, tsknm ):
    return self.taskdict[tsknm][1]
    
  def get_commands( self, tsknm ):
    return self.taskdict[tsknm][2]

  def run_program( self, prgm, args, cmds ):
    import os, subprocess
    bin = os.path.join( os.environ["CCP4"], "bin", prgm )
    if ( not os.path.exists( bin ) ):
      bin = prgm  # if binary isn't in CBIN, assume absolute or path
    # start of windows compatibility code
    if ( os.name == 'NT' ):
      bin = bin.strip() + '.exe'
      bin.replace( '\\\\', '/' )
      args.replace( '\\\\', '/' )
      cmds.replace( '\\\\', '/' )
    # end of windows comatibility code
    arglist = [bin] + args.split()
    process = subprocess.Popen( arglist, stdin=subprocess.PIPE )
    process.stdin.write( cmds )
    process.stdin.close()
    self.status = process.wait()

  def run_task( self, tsknm ):
    p = self.get_program( tsknm )
    a = self.get_arguments( tsknm )
    c = self.get_commands( tsknm )
    self.run_program( p, a, c )
    if self.status != 0:
      raise( StandardError( 'Fail in program <'+p+'>, task <'+tsknm+'>' ) )

  def read( self, path ):
    f = file( path, 'r' ); s = f.read(); f.close()
    return s

  def readlines( self, path ):
    f = file( path, 'r' ); s = f.readlines(); f.close()
    return s

  def write( self, path, txt ):
    f = file( path, 'w' ); f.write( txt ); f.close()

  def copy( self, src, dst ):
    import shutil
    shutil.copy( src, dst )

  def remove( self, path ):
    import os
    os.remove( path )
"""

# control commands for input

cmdin = 'control = Control( """'+task+'""" )'

# clean up code

clnup = 'status = control.status'

# now run the task

globl = {}
local = {}
exec clsin in globl, local
exec cmdin in globl, local
try:
  exec ctrl  in globl, local
except Exception, err:
  print err
exec clnup in globl, local

status = local['status']

# output control code and status

print
for line in ctrl.split( '\n' ):
  print '#', line
print '# PROGRAM STATUS <',status,'>'

# exit
sys.exit(status)
