import hashlib
import subprocess
import os
import tempfile

devnull = open(os.devnull, 'w')

binpath="./bin/"
examplepath="./examples/"
trinculo = binpath + "/trinculo"

tmpdir=tempfile.mkdtemp()

print "Testing trinculo (v0.95)"
print "Test files are written to: " + tmpdir
print "1. Testing frequentist association (plink)...",

test1 = subprocess.call([trinculo,"multinom","--bfile", examplepath + "/genotypes","--pheno", examplepath + "/phenos.txt","--phenoname","Pheno","--basepheno","Control","--out", tmpdir + "/1"],stdout=devnull, stderr=devnull)

stoptest=False
if test1 != 0:
    print "FAILED (trinculo returned non-zero code " + str(test1) + ")"
    stoptest=True 

if not stoptest:
    test2 = os.path.isfile(tmpdir + "/1" + ".log") and os.path.isfile(tmpdir + "/1" + ".assoc.multinom")
    if not test2:
        print "FAILED (trinuculo failed to produce expected files)"
        stoptest=True
if not stoptest:
    test3 = hashlib.md5(file(tmpdir + '/1.assoc.multinom').read()).digest()
    if test3 != '\x1dg(d\xde\xccM\xcdHM\x11\xdd\xee\xfa\x02\xc6':
        print "FAILED (trinculo produced file with incorrect MD5 sum: " + tmpdir + '/1.assoc.multinom)'
        stoptest=True

if not stoptest:
    print "PASSED"


print "2. Testing frequentist association (dosage)...",

test1 = subprocess.call([trinculo,"multinom","--dosage", examplepath + "/genotypes.dose","--pheno", examplepath + "/phenos.txt","--phenoname","Pheno","--basepheno","Control","--out", tmpdir + "/2"],stdout=devnull, stderr=devnull)

stoptest=False
if test1 != 0:
    print "FAILED (trinculo returned non-zero code " + str(test1) + ")"
    stoptest=True 

if not stoptest:
    test2 = os.path.isfile(tmpdir + "/2" + ".log") and os.path.isfile(tmpdir + "/2" + ".assoc.multinom")
    if not test2:
        print "FAILED (trinuculo failed to produce expected files)"
        stoptest=True

if not stoptest:
    test3 = hashlib.md5(file(tmpdir + '/2.assoc.multinom').read()).digest()
    if test3 != '=6\xd0\xb3\xd8\x15SW\x8f\xf9\x86\x13\x99\x90S\xba':
        print "FAILED (trinculo produced file with incorrect MD5 sum: " + tmpdir + '/2.assoc.multinom)'
        stoptest=True

if not stoptest:
    print "PASSED"
  
print "3. Testing frequentist association (covariates)...",

test1 = subprocess.call([trinculo,"multinom","--bfile", examplepath + "/genotypes","--pheno", examplepath + "/phenos.txt","--phenoname","Pheno","--basepheno","Control","--covar", examplepath + "/pcs.txt","--out", tmpdir + "/3"],stdout=devnull, stderr=devnull)

stoptest=False
if test1 != 0:
    print "FAILED (trinculo returned non-zero code " + str(test1) + ")"
    stoptest=True

if not stoptest:
    test2 = os.path.isfile(tmpdir + "/3" + ".log") and os.path.isfile(tmpdir + "/3" + ".assoc.multinom")
    if not test2:
        print "FAILED (trinuculo failed to produce expected files)"
        stoptest=True

if not stoptest:
    test3 = hashlib.md5(file(tmpdir + '/3.assoc.multinom').read()).digest()
    if test3 != '\x16\x03\xb7\xaaD~M\x04\xba\xff\xc5\xef\xfd{r7':
        print "FAILED (trinculo produced file with incorrect MD5 sum: " + tmpdir + '/3.assoc.multinom)'
        stoptest=True

if not stoptest:
    print "PASSED"


print "4. Testing frequentist association (conditioning)...",

condfile=tempfile.mkstemp()
file(condfile[1],"w").write("SNP1")

test1 = subprocess.call([trinculo,"multinom","--bfile", examplepath + "/genotypes","--pheno", examplepath + "/phenos.txt","--phenoname","Pheno","--basepheno","Control","--covar", examplepath + "/pcs.txt","--condition",condfile[1],"--out", tmpdir + "/4"],stdout=devnull, stderr=devnull)

stoptest=False
if test1 != 0:
    print "FAILED (trinculo returned non-zero code " + str(test1) + ")"
    stoptest=True

if not stoptest:
    test2 = os.path.isfile(tmpdir + "/4" + ".log") and os.path.isfile(tmpdir + "/4" + ".assoc.multinom")
    if not test2:
        print "FAILED (trinuculo failed to produce expected files)"
        stoptest=True

if not stoptest:
    test3 = hashlib.md5(file(tmpdir + '/4.assoc.multinom').read()).digest()
    if test3 != ":\x03'\x9be=\x08\xbas\xea\xc7\xf2_N\xe3\x02":
        print "FAILED (trinculo produced file with incorrect MD5 sum: " + tmpdir + '/4.assoc.multinom)'
        stoptest=True

if not stoptest:
    print "PASSED"


print "5. Testing Bayesian association...",

test1 = subprocess.call([trinculo,"multinom","--bfile", examplepath + "/genotypes","--pheno", examplepath + "/phenos.txt","--phenoname","Pheno","--basepheno","Control","--covar", examplepath + "/pcs.txt","--normalize","--defaultprior","--out", tmpdir + "/5"],stdout=devnull, stderr=devnull)

stoptest=False
if test1 != 0:
    print "FAILED (trinculo returned non-zero code " + str(test1) + ")"
    stoptest=True

if not stoptest:
    test2 = os.path.isfile(tmpdir + "/5" + ".log") and os.path.isfile(tmpdir + "/5" + ".assoc.multinom")
    if not test2:
        print "FAILED (trinuculo failed to produce expected files)"
        stoptest=True

if not stoptest:
    test3 = hashlib.md5(file(tmpdir + '/5.assoc.multinom').read()).digest()
    if test3 != 'A~\x85\x00Zy^OsG_\xa9\xa7\xc5\r\xe3':
        print "FAILED (trinculo produced file with incorrect MD5 sum: " + tmpdir + '/5.assoc.multinom)'
        stoptest=True

if not stoptest:
    print "PASSED"


print "6. Testing Bayesian association (prior file)...",

test1 = subprocess.call([trinculo,"multinom","--bfile", examplepath + "/genotypes","--pheno", examplepath + "/phenos.txt","--phenoname","Pheno","--basepheno","Control","--covar", examplepath + "/pcs.txt","--normalize","--priors",examplepath + "/priors.txt","--out", tmpdir + "/6"],stdout=devnull, stderr=devnull)

stoptest=False
if test1 != 0:
    print "FAILED (trinculo returned non-zero code " + str(test1) + ")"
    stoptest=True

if not stoptest:
    test2 = os.path.isfile(tmpdir + "/6" + ".log") and os.path.isfile(tmpdir + "/6" + ".assoc.multinom")
    if not test2:
        print "FAILED (trinuculo failed to produce expected files)"
        stoptest=True

if not stoptest:
    test3 = hashlib.md5(file(tmpdir + '/6.assoc.multinom').read()).digest()
    if test3 != 'A~\x85\x00Zy^OsG_\xa9\xa7\xc5\r\xe3':
        print "FAILED (trinculo produced file with incorrect MD5 sum: " + tmpdir + '/6.assoc.multinom)'
        stoptest=True

if not stoptest:
    print "PASSED"



print "7. Testing Bayesian model selection...",

test1 = subprocess.call([trinculo,"multinom","--bfile", examplepath + "/genotypes","--pheno", examplepath + "/phenos.txt","--phenoname","Pheno","--basepheno","Control","--covar", examplepath + "/pcs.txt","--normalize","--defaultprior","--select","--out", tmpdir + "/7"],stdout=devnull, stderr=devnull)

stoptest=False
if test1 != 0:
    print "FAILED (trinculo returned non-zero code " + str(test1) + ")"
    stoptest=True

if not stoptest:
    test2 = os.path.isfile(tmpdir + "/7" + ".log") and os.path.isfile(tmpdir + "/7" + ".assoc.multinom") and os.path.isfile(tmpdir + "/7" + ".select.multinom")
    if not test2:
        print "FAILED (trinuculo failed to produce expected files)"
        stoptest=True

if not stoptest:
    test3 = hashlib.md5(file(tmpdir + '/7.select.multinom').read()).digest()
    if test3 != "9\xb9\xfa\xdf\x02'\xdcx\x82U\xce\xcf\xecx\x06!":
        print "FAILED (trinculo produced file with incorrect MD5 sum: " + tmpdir + '/7.select.multinom)'
        stoptest=True

if not stoptest:
    print "PASSED"

print "8. Testing Bayesian model selection (empirical prior)...",

test1 = subprocess.call([trinculo,"multinom","--bfile", examplepath + "/genotypes","--pheno", examplepath + "/phenos.txt","--phenoname","Pheno","--basepheno","Control","--covar", examplepath + "/pcs.txt","--normalize","--empiricalprior","--select","--out", tmpdir + "/8"],stdout=devnull, stderr=devnull)

stoptest=False
if test1 != 0:
    print "FAILED (trinculo returned non-zero code " + str(test1) + ")"
    stoptest=True

if not stoptest:
    test2 = os.path.isfile(tmpdir + "/8" + ".log") and os.path.isfile(tmpdir + "/8" + ".assoc.multinom") and os.path.isfile(tmpdir + "/8" + ".select.multinom") and os.path.isfile(tmpdir + "/8" + ".prior")
    if not test2:
        print "FAILED (trinuculo failed to produce expected files)"
        stoptest=True

if not stoptest:
    test3 = hashlib.md5(file(tmpdir + '/8.select.multinom').read()).digest()
    if test3 != '\x89_3\xf2\xef\x96\x1e\xac\x8dy\xc8\xbf\x14\x1f\xfa%':
        print "FAILED (trinculo produced file with incorrect MD5 sum: " + tmpdir + '/8.select.multinom)'
        stoptest=True

if not stoptest:
    print "PASSED"

print "9. Testing ordinal regression...",



test1 = subprocess.call([trinculo,"ordinal","--bfile", examplepath + "/genotypes","--pheno", examplepath + "/phenos.txt","--phenoname","Order","--covar", examplepath + "/pcs.txt","--out", tmpdir + "/9"],stdout=devnull, stderr=devnull)

stoptest=False
if test1 != 0:
    print "FAILED (trinculo returned non-zero code " + str(test1) + ")"
    stoptest=True

if not stoptest:
    test2 = os.path.isfile(tmpdir + "/9" + ".log") and os.path.isfile(tmpdir + "/9" + ".assoc.ordinal")
    if not test2:
        print "FAILED (trinuculo failed to produce expected files)"
        stoptest=True

if not stoptest:
    test3 = hashlib.md5(file(tmpdir + '/9.assoc.ordinal').read()).digest()
    if test3 != '\xbd\xab\xad\x10\xd3\xea\xd8r\x9f*~V\xf8\xb5\x9b\x9c':
        print "FAILED (trinculo produced file with incorrect MD5 sum: " + tmpdir + '/9.assoc.ordinal)'
        stoptest=True

if not stoptest:
    print "PASSED"
