#!/usr/bin/env python3

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

#Version  Nov. 6, 2024
# Run D3HOM, D4HOM as a command
#Synopsis: dxhom.py ifn strand outfile startx finishx starty\
#            finishy range minper compfact kind linesize program


""" ensure that there are enough command line arguments to parse """
if len(sys.argv) < 13:
    print("Usage: dxhom.py  SEQFILEX  SEQFILEY  OUTFILE  STARTX  FINISHX  STARTY  FINISHY")
    print("         RANGE  MINPER  COMPFACT  LINESIZE  PROGRAM")
    exit();


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

# Abort if INFILE does not exist or is of zero length
if os.path.exists(IFN) and os.path.getsize(IFN) > 1 :

    PID = str(os.getpid()) #process id
    NL = "\n"

    # Write the next GenBank Entry from INFILE to OUTFILE, and return the length
    # of the sequence.
    def MakeGBFile(infile,OUTFN) :
        LEN = 0
        outfile = open(OUTFN,"w")
        NEXTLINE = infile.readline()
        if len(NEXTLINE) > 0 :
            TOKENS = NEXTLINE.split()
            if TOKENS[0] == "LOCUS" :
                LEN = int(TOKENS[2])
                outfile.write(NEXTLINE)
                while not NEXTLINE.startswith("/") and not NEXTLINE == "":
                    NEXTLINE = infile.readline()
                    outfile.write(NEXTLINE)
        outfile.close()
        return LEN

    SEQFILEX = IFN + '.X.' + PID
    SEQFILEY = IFN + '.Y.' + PID
    OKAY = True
    infile = open(IFN,'r')
    # We only create files for the first two GenBank entries in infile,
    # and ignore the rest, if any.
    SEQLENGTHX = MakeGBFile(infile,SEQFILEX)
    SEQLENGTHY = MakeGBFile(infile,SEQFILEY)
    infile.close()

    # Sanity checking
    if SEQLENGTHX < 1 or SEQLENGTHY < 1 :
        OKAY = False 

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

    if STARTY > SEQLENGTHY:
        STARTY = SEQLENGTHY
    if FINISHY > SEQLENGTHY:
        FINISHY = SEQLENGTHY

    # Abort if parameters aren't set up properly.
    # Right now we don't do any checking, but we have this
    # step for any future checking.
    if not OKAY:
        print('>>> Aborting program.')
        exit()
    else:       
        # ------------------- Generate a file of commands to be read by D3HOM or D4HOM ----------
        COMFN = 'dxhom.py' + '.COM.' + PID
        comfile = open(COMFN, 'w')

        # Open files
        comfile.write(SEQFILEX + NL)
        comfile.write('g' + NL)
        comfile.write(STRAND + NL)
        comfile.write(SEQFILEY + NL)
        comfile.write('g' + NL)
        comfile.write(OUTFILE + NL) 

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

        comfile.write('1\n')     #choose startx
        comfile.write(str(STARTX) + NL)

        comfile.write('2\n')      #choose finishx
        comfile.write(str(FINISHX) + NL)

        comfile.write('3\n')      #choose startx
        comfile.write(str(STARTY) + NL)

        comfile.write('4\n')      #choose finishx
        comfile.write(str(FINISHY) + NL)

        comfile.write('5\n')      #choose range
        comfile.write(str(RANGE) + NL)

        comfile.write('7\n')      #choose minper
        comfile.write(str(MINPER) + NL)

        comfile.write('8\n')      #choose compfact
        comfile.write(str(COMPFACT) + NL)

        comfile.write('9\n')      #choose kind
        comfile.write(KIND + NL)

        comfile.write('10\n')     #choose linesize
        comfile.write(str(LINESIZE) + NL)

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

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

        comfile.write('0\n')       #exit program
        comfile.close()

        # run d3hom or d4hom and then clean up temporary files (no temporary files in python version)
        comfile = open(COMFN, 'r')
        p = subprocess.Popen([PROGRAM], stdin=comfile)
        p.wait()
        comfile.close()
        os.remove(COMFN)
        os.remove(SEQFILEX)
        os.remove(SEQFILEY)
