#!/usr/bin/env python

import re
import os
import os.path
import subprocess
import sys

#Version  Jan. 8, 2020
# Run D3HOM, D4HOM as a command
#Synopsis: dxhom.py seqfilex strand seqfiley outfile startx finishx starty\
#            finishy range minper compfact kind linesize program

#Convert arguments to variables
SEQFILEX = sys.argv[1]
STRAND   = sys.argv[2]
SEQFILEY = sys.argv[3]
OUTFILE  = sys.argv[4]
STARTX   = int(sys.argv[5])
FINISHX  = int(sys.argv[6])
STARTY   = int(sys.argv[7])
FINISHY  = int(sys.argv[8])
RANGE    = int(sys.argv[9])
MINPER   = int(sys.argv[10])
COMPFACT = int(sys.argv[11])
KIND     = sys.argv[12]
LINESIZE = int(sys.argv[13])
PROGRAM  = sys.argv[14]

#-----------   error checking ---------------------
# Abort if INFILE does not exist or is of zero length
if os.path.exists(SEQFILEX) and os.path.getsize(SEQFILEX) > 1 and  os.path.exists(SEQFILEY) and os.path.getsize(SEQFILEY) > 1 :

#if SEQFILEX != 0 and SEQFILEY != 0:
    OKAY = True
    PID = str(os.getpid()) #process id

    # Correct for bug in GDE2.2, which writes 'Circular' in wrong columns
    # in GenBank LOCUS line. This is done by determining whether seq is
    # linear or circular, converting to Pearson format, and appending the
    # '1' if linear or '2' if circular. We also have to work around a bug
    # in readseq that causes it to write 'Circular' on the DEFINITION line
    # ARRRGH!
    for file in (SEQFILEX, SEQFILEY):
        file_h = open(file, 'r')
        # check the first two lines (as indicated by the algorithm)
        #head -2 $file |egrep -e '[Cc]ircular' > circ.$PID
        if re.search('[Cc]ircular', file_h.readline()) or re.search('[Cc]ircular', file_h.readline()):
            TOPOLOGY = '1'
        else:
            TOPOLOGY = '2'
        file_h.close()

#       readseq  -i1 -f8 $file >$file.$PID
        subprocess.call(['readseq', '-i1', '-ffasta', '-o=' + file + '.' + PID, file])

        h_file_pid = open(file + '.' + PID, 'a')
        h_file_pid.write(TOPOLOGY + '\n')
        h_file_pid.close()
   
    # Determine the size of seq. in seqfilex  and seqfiley and make sure that
    # start and finish values aren't greater than seq. length.
    # The following line was broken by Fedora5, so we'll use grep instead.
    #tail +2 $SEQFILEX.$PID > TEMP.$PID
    #grep -v '>' < $SEQFILEX.$PID > TEMP.$PID
    #@ SEQLENGTHX = (`wc -c < TEMP.$PID` - `wc -l < TEMP.$PID`) - 1
    SEQLENGTHX = 0
    h_INFILE = open(SEQFILEX + '.' + PID, 'r')
    for line in h_INFILE:
        if not line.startswith('>'):
            SEQLENGTHX += len(line) - 1
    h_INFILE.close()
    SEQLENGTHX -= 1


    if STARTX > SEQLENGTHX:
        STARTX = SEQLENGTHX
    if FINISHX > SEQLENGTHX:
        FINISHX = SEQLENGTHX


    #tail +2 $SEQFILEY.$PID > TEMP.$PID
    #grep -v '>' < $SEQFILEY.$PID > TEMP.$PID
    #@ SEQLENGTHY = (`wc -c < TEMP.$PID` - `wc -l < TEMP.$PID`) - 1
    SEQLENGTHY = 0
    h_INFILE = open(SEQFILEY + '.' + PID, 'r')
    for line in h_INFILE:
        if not line.startswith('>'):
            SEQLENGTHY += len(line) - 1
    h_INFILE.close()
    SEQLENGTHY -= 1

    if STARTY > SEQLENGTHY:
        STARTY = SEQLENGTHY
    if FINISHY > SEQLENGTHY:
        FINISHY = SEQLENGTHY
   
    # Abort if parameters aren't set up properly.
    if not OKAY:
        print('>>> Aborting program.')
        exit()
   
    # run d3hom or d4hom and then clean up temporary files (no temporary files in python version)
    p = subprocess.Popen([PROGRAM], stdin=subprocess.PIPE)
    #----------------- generate keyboard input to send to program -----

    # Open files
    p.stdin.write(SEQFILEX + '.' + PID + '\n')
    p.stdin.write('b\n')
    p.stdin.write(STRAND + '\n')
    p.stdin.write(SEQFILEY + '.' + PID + '\n')
    p.stdin.write('b\n')
    p.stdin.write(OUTFILE + '\n')

    # Set parameters
    p.stdin.write('4\n')     #Choose parameter menu

    p.stdin.write('1\n')     #choose startx
    p.stdin.write(str(STARTX) + '\n')

    p.stdin.write('2\n')      #choose finishx
    p.stdin.write(str(FINISHX) + '\n')

    p.stdin.write('3\n')      #choose startx
    p.stdin.write(str(STARTY) + '\n')

    p.stdin.write('4\n')      #choose finishx
    p.stdin.write(str(FINISHY) + '\n')

    p.stdin.write('5\n')      #choose range
    p.stdin.write(str(RANGE) + '\n')

    p.stdin.write('7\n')      #choose minper
    p.stdin.write(str(MINPER) + '\n')

    p.stdin.write('8\n')      #choose compfact
    p.stdin.write(str(COMPFACT) + '\n')

    p.stdin.write('9\n')      #choose kind
    p.stdin.write(KIND + '\n')

    p.stdin.write('10\n')     #choose linesize
    p.stdin.write(str(LINESIZE) + '\n')

    p.stdin.write('0\n')       #exit parameter menu

    p.stdin.write('6\n')       #write output to file

    p.stdin.write('0\n')       #exit program
    p.stdin.close()
    p.wait()
