#!/usr/bin/env python3

import string
import os
import sys

#Version Apr. 27, 2020
# Creates an input file for primer3
#Synopsis: primer.py infile maxprimers optlen minlen maxlen opttemp mintemp
#  maxtemp mingc maxgc saltconc dnaconc minunk maxself max3pself gcclamp
#  minprod maxprod target targetstart targetend 
#  intoligo iopttemp imintemp
#  imaxtemp imingc imaxgc isaltconc idnaconc iminunk imaxself imax3pself

#Convert arguments to variables
INFILE         = sys.argv[1]
MAXPRIMERS     = sys.argv[2]
OPTLEN         = sys.argv[3]
MINLEN         = sys.argv[4]
MAXLEN         = sys.argv[5]
OPTTEMP        = sys.argv[6]
MINTEMP        = sys.argv[7]
MAXTEMP        = sys.argv[8]
MINGC          = sys.argv[9]
MAXGC          = sys.argv[10]
SALTMONOVALENT = sys.argv[11]
DNACONC        = sys.argv[12]
MAXUNK         = sys.argv[13]
MAXSELF        = sys.argv[14]
MAX3PSELF      = sys.argv[15]
GCCLAMP        = sys.argv[16]
MINPROD        = sys.argv[17]
MAXPROD        = sys.argv[18]
TARGET         = sys.argv[19]
TARGETSTART    = sys.argv[20]
TARGETEND      = sys.argv[21]
intoligo       = sys.argv[22]
ioptlen        = sys.argv[23]
iminlen        = sys.argv[24]
imaxlen        = sys.argv[25]
iopttemp       = sys.argv[26]
imintemp       = sys.argv[27]
imaxtemp       = sys.argv[28]
imingc         = sys.argv[29]
imaxgc         = sys.argv[30]
isaltconc      = sys.argv[31]
idnaconc       = sys.argv[32]
imaxunk        = sys.argv[33]
imaxself       = sys.argv[34]
imax3pself     = sys.argv[35]

#PID = os.getpid() #process id

# primer3 appears to accept input files in which every line is in the form
#<parameter_name>=<value>
#The file is terminated by a line containing a single '=' sign.

#Write the sequence name

print("SEQUENCE_ID=" + INFILE) 

SEQLENGTH = 0
SEQLINE='SEQUENCE_TEMPLATE='

# Write out the sequence as a single long line. Also determine the length of seq.
NUMLINES = 0
#trantable = string.maketrans("uU", "tT") # python2
#This will be the usage in Python 3
trantable = str.maketrans("uU", "tT", "\n")

h_INFILE = open(INFILE, 'r')
for line in h_INFILE:
    NUMLINES += 1
    if NUMLINES != 1:
        SEQLENGTH += len(line)
        # Incredibly, PRIMER3 can't handle RNA, so we change U's to T's.
        # We also need to strip newline characters out so that the sequence
        # will print as a single line, which is required by primer3.
        SEQLINE= SEQLINE + line.translate(trantable)
#Make sure sequence ends with a \n
print(SEQLINE)

# Make sure parameters are reasonable
if  int(MINPROD) > int(MAXPROD):
    MINPROD = MAXPROD

if int(MINPROD) > SEQLENGTH:
    MINPROD = SEQLENGTH

if int(MAXPROD) < int(MINPROD):
    MAXPROD = MINPROD

if int(MAXPROD) > SEQLENGTH:
    MAXPROD = SEQLENGTH

# Write parameters

# Global parameters
print("PRIMER_NUM_RETURN=" + MAXPRIMERS)
print("PRIMER_OPT_SIZE=" + OPTLEN)
print("PRIMER_MIN_SIZE=" + MINLEN)
print("PRIMER_MAX_SIZE=" + MAXLEN)
print("PRIMER_OPT_TM=" + OPTTEMP)
print("PRIMER_MIN_TM=" + MINTEMP)
print("PRIMER_MAX_TM=" + MAXTEMP)
print("PRIMER_MIN_GC=" + MINGC)
print("PRIMER_MAX_GC=" + MAXGC)
print("PRIMER_SALT_MONOVALENT=" + SALTMONOVALENT)
print("PRIMER_DNA_CONC=" + DNACONC)
print("PRIMER_MAX_NS_ACCEPTED=" + MAXUNK)
print("PRIMER_MAX_SELF_ANY=" + MAXSELF)
print("PRIMER_MAX_SELF_END=" + MAX3PSELF)
print("PRIMER_GC_CLAMP=" + GCCLAMP)
#print("PRIMER_DEFAULT_PRODUCT=" + str(int(MINPROD) - int(MAXPROD)))
print("PRIMER_LIBERAL_BASE=1")
print("P3_FILE_FLAG=1")
print("PRIMER_EXPLAIN_FLAG=1")

# The primer3 syntax for specifying a target fragment is 
# SEQUENCE_TARGET=start,len
# I find this counterintuitive, so we let the user just specify
# start and end points, which could be found directly in sequence
# feature documentation. Here we do the work of calculating the
# target length, and doing sanity checking.
if TARGET == "1":
    TARGETSTART = int(TARGETSTART)
    TARGETEND = int(TARGETEND)
    if (1 <= TARGETSTART <= SEQLENGTH) and (TARGETSTART <= TARGETEND <= SEQLENGTH) :
        TARGETLEN=TARGETEND-TARGETSTART+1
        print("SEQUENCE_TARGET=" + str(TARGETSTART) + ',' + str(TARGETLEN))
        print("PRIMER_PRODUCT_SIZE_RANGE=" + str(TARGETLEN) + '-' + str(SEQLENGTH))
else:
    print("PRIMER_PRODUCT_SIZE_RANGE=" + str(MINPROD) + '-' + str(MAXPROD))

# Internal oligo parameters
if intoligo == "1":
    print("PRIMER_PICK_INTERNAL_OLIGO=" + intoligo)
    print("PRIMER_INTERNAL_OPT_SIZE=" + ioptlen)
    print("PRIMER_INTERNAL_MIN_SIZE=" + iminlen)
    print("PRIMER_INTERNAL_MAX_SIZE=" + imaxlen)
    print("PRIMER_INTERNAL_OPT_TM=" + iopttemp)
    print("PRIMER_INTERNAL_MIN_TM=" + imintemp)
    print("PRIMER_INTERNAL_MAX_TM=" + imaxtemp)
    print("PRIMER_INTERNAL_MIN_GC=" + imingc)
    print("PRIMER_INTERNAL_MAX_GC=" + imaxgc)
    print("PRIMER_INTERNAL_SALT_MONOVALENT=" + isaltconc)
    print("PRIMER_INTERNAL_DNA_CONC=" + idnaconc)
    print("PRIMER_INTERNAL_MAX_NS_ACCEPTED=" + imaxunk)
    print("PRIMER_INTERNAL_MAX_SELF_ANY=" + imaxself)
    print("PRIMER_INTERNAL_MAX_SELF_END=" + imax3pself)

# Terminate record
print('=')
sys.stdout.flush()

# Delete temporary files
#for f in os.listdir(os.getcwd()):
#    if not os.path.isdir(f) and str("." + PID) in f:
#        os.remove(os.path.join(os.getcwd(), f))
#os.remove(INFILE)

