#!/usr/bin/python

import argparse
import platform
import shutil
import sys
import pycurl
import os
from subprocess import call
from StringIO import StringIO
import traceback
import xmltodict

def SetNSSM(nssmpath,drivername,property,value):
    cmd = "\"" + nssmpath + "\" set \"" + drivername + "\" " + property + " " + value
    call(cmd, shell=True)
    #print cmd

def WindowsInstaller(inport, outport):
    print "Installing Driver for Windows..."
    pathtopython = "c:\\Python27\\python.exe"
    pathtotwisted = "c:\\Python27\\scripts\\twistd.py"
    
    is64 = False
    if platform.machine().endswith('64'):
        is64 = True

    basepath = os.path.dirname(os.path.realpath(__file__))
    
    nssmpath = basepath
    if is64:
        nssmpath = nssmpath + "\\nssm\\win64"
    else:
        nssmpath = nssmpath + "\\nssm\\win32"

    nssmpath = nssmpath + "/nssm.exe"    
    print "Creating NSS Service..."

    drivername = "ARDI Consolidator " + str(outport)

    #Installing the base service...
    cmd = "\"" + nssmpath + "\" install \"" + drivername + "\" \"" + pathtopython + "\" \"\"\"" + pathtotwisted + " " + "\"\"\" ardicon --inport=" + str(inport) + " --outport=" + str(outport)
    call(cmd, shell=True)
    #print "Running - " + cmd    

    #Redirection of I/O...
    SetNSSM(nssmpath,drivername,"AppDirectory",basepath)
    SetNSSM(nssmpath,drivername,"AppStderr","c:\\windows\\temp\\ardicon" + str(outport) + ".log")
    SetNSSM(nssmpath,drivername,"AppStderrCreationDisposition","2")
    SetNSSM(nssmpath,drivername,"AppStdout","c:\\windows\\temp\\ardicon" + str(outport) + ".log")
    SetNSSM(nssmpath,drivername,"AppStdoutCreationDisposition","2")    
    SetNSSM(nssmpath,drivername,"AppRotateFiles","1")
    SetNSSM(nssmpath,drivername,"AppRotateBytes","1048576")

    #Prevent Windows Event-Style Terminations (Useless on Python apps)
    SetNSSM(nssmpath,drivername,"AppStopMethodSkip","6")    
    
    print "Starting NSS Service..."
    
    cmd = "\"" + nssmpath + "\" start \"" + drivername + "\""
    call(cmd, shell=True)
    #print "Running - " + cmd

def WindowsUninstaller(outport):
    is64 = False
    if platform.machine().endswith('64'):
        is64 = True

    basepath = os.path.dirname(os.path.realpath(__file__))
    nssmpath = basepath
    if is64:
        nssmpath = nssmpath + "\\nssm\\win64"
    else:
        nssmpath = nssmpath + "\\nssm\\win32"

    nssmpath = nssmpath + "/nssm.exe"

    drivername = "ARDI Consolidator " + str(outport)

    cmd = "\"" + nssmpath + "\" stop \"" + drivername + "\""
    call(cmd, shell=True)

    cmd = "\"" + nssmpath + "\" remove \"" + drivername + "\" confirm"
    call(cmd, shell=True)

    
def LinuxInstaller(inport, outport):
    
    print "Installing Driver for Linux..."
    
    basepath = os.path.dirname(os.path.realpath(__file__))
    lxpath = basepath + "/linux"
    
    #finalpath = finalpath + " " + str(portno)
    
    print "Creating init.d Script..."
    file = open(lxpath + '/init','r')
    fl = file.read()
    file.close()
    st = str(fl)
    
    st = st.replace("$INPORT$",str(inport))
    st = st.replace("$OUTPORT$",str(outport))
    
    initpath = "/etc/init.d/ardicon-" + str(outport)
    file = open(initpath,'w')
    file.write(st)
    file.flush()
    file.close()  
    
    call("chmod gu+x " + initpath,shell=True)
        
    print "Setting Runlevel..."
    call("update-rc.d ardicon-" + str(portno) + " defaults", shell=True)
    
    print "Creating Log Files..."
    logpath = "/var/log/ardi/consolidator-" + str(portno) + ".log"
    call("touch " + logpath, shell=True)
    call("chmod a+r " + logpath, shell=True)
        
    print "Starting Service..."

    call("service ardicon-" + str(portno) + " start" , shell=True)

def LinuxUninstaller(outport):
    
    print "Removing Driver for Linux..."
    
    print "Shutting Down Driver"
    cmd = "service ardicon-" + str(outport) + " stop"
    call(cmd, shell=True)
    
    print "Removing From Boot"
    cmd = "update-rc.d  ardicon-"+ str(outport) + " remove"
    call(cmd, shell=True)
    
    print "Removing Service Definition"
    cmd = "rm /etc/init.d/ardicon-" + str(outport)
    call(cmd, shell=True)

parser = argparse.ArgumentParser(description="Manage ARDI Profile Live Consolidators")
parser.add_argument('action', help='\'install\' or \'remove\'')
parser.add_argument('inport', help='The submission port for the driver')
parser.add_argument('outport', help='The external/access port for the driver')

args = parser.parse_args()
    
is_admin = False

import ctypes, os
try:
    is_admin = os.geteuid() == 0
except AttributeError:
    is_admin = ctypes.windll.shell32.IsUserAnAdmin() != 0
    
  
if is_admin == False:
    print "Error: This must be run as root/an Administrator"
    sys.exit(0)        

#Install driver as a service...
inport = int(args.inport)
outport = int(args.outport)

print "Installing " + str(outport) + " Profile Consolidator"

ActionName = "Installed"

if args.action == "install":
    if platform.system() == "Windows":
        WindowsInstaller(inport,outport)
        pass
    else:
        LinuxInstaller(inport,outport)
        pass

if args.action == "remove":
    ActionName = "Removed"
    if platform.system() == "Windows":
        WindowsUninstaller(outport)
        pass
    else:
        LinuxUninstaller(outport)
        pass

print "ARDI Profile Consolidator Service " + ActionName