#!/usr/bin/ardipython

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

def SetNSSM(nssmpath,drivername,property,value):
    cmd = "\"" + nssmpath + "\" set \"" + drivername + "\" " + property + " " + value
    call(cmd, shell=True)
    #print cmd
	
def WindowsUninstaller(addon,url,ext):
    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 " + addon + " Service for " + ext

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

    cmd = "\"" + nssmpath + "\" remove \"" + drivername + "\" confirm"
    call(cmd, shell=True)
    #print "Running - " + cmd
    
def LinuxUninstaller(addon,url,ext):    
    print("Shutting Down Addon Service")
    cmd = "service ardi-" + addon + "-" + ext + " stop"
    call(cmd, shell=True)

    print("Removing Service Definition")
    cmd = "rm /etc/init.d/ardi-" + addon + "-" + ext
    call(cmd, shell=True)
    
    print("Removing From Boot")
    cmd = "update-rc.d ardi-" + addon + "-" + ext + " remove"
    call(cmd, shell=True)

def WindowsInstaller(addon,url,ext):
    print("Installing Addon Service for Windows...")
    
    #Get Python Location
    pathtopython = "c:\\python27\\python.exe"
    try:
        pathtopython = os.getenv('ARDIPythonPath')
    except:
        pass
    
    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 " + addon+ " Service for " + ext

    #Installing the base service...
    cmd = "\"" + nssmpath + "\" install \"" + drivername + "\" \"" + pathtopython + "\" \"\"\"" + basepath + "\\..\\services\\" + addon + "\\" + addon + ".py " + "\"\"\" " + url
    call(cmd, shell=True)
    print("Running - " + cmd)  

    #Redirection of I/O...
    SetNSSM(nssmpath,drivername,"AppStderr","c:\\windows\\temp\\ardi-" + addon + "-" + ext + ".log")
    SetNSSM(nssmpath,drivername,"AppStderrCreationDisposition","2")
    SetNSSM(nssmpath,drivername,"AppStdout","c:\\windows\\temp\\ardi-" + addon + "-" + ext + "o.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 LinuxInstaller(addon, url, ext):
    
    print("Installing Addon Service for Linux...")
    
    basepath = os.path.dirname(os.path.realpath(__file__))
    lxpath = basepath + "/linux"
    
    #print "Creating Daemon Script..."
    #file = open(lxpath + '/daemon_addon.py','r')
    #fl = file.read()
    #file.close()
    #st = str(fl)
    #st = st.replace("$ADDON$",str(addon))
    #st = st.replace("$SERVER$",url)
    finalpath = basepath + "/../srv/" + addon + "/" + addon + ".py"
    #file = open(finalpath,'w')
    #file.write(st)
    #file.flush()
    #file.close()
    
    print("Marking File as Executable...")
    call("chmod gu+x " + finalpath, shell=True)
    
    #finalpath = finalpath + " " + str(portno)
    
    print("Creating init.d Script...")
    file = open(lxpath + '/init_addon','r')
    fl = file.read()
    file.close()
    st = str(fl)
    st = st.replace("$SERVICENAME$","ardi-" + addon + "-" + ext)
    st = st.replace("$FULLPATH$",finalpath)
    st = st.replace("$ADDON$",addon)
    st = st.replace("$SERVER$",url)
    initpath = "/etc/init.d/ardi-" + addon + "-" + ext
    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 ardi-" + addon + "-" + ext + " defaults", shell=True)
    
    print("Creating Log Files...")
    logpath = "/var/log/ardi/addon-" + addon + "-" + ext + ".log"
    call("touch " + logpath, shell=True)
    call("chmod a+r " + logpath, shell=True)
        
    print("Starting Service...")

    call("service ardi-" + addon + "-" + ext + " start" , shell=True)
    
def GetAddonDetails(remotehost,code):    
    try:
        #buf = StringIO()
        
        url = 'http://' + remotehost + '/api/addon?code=' + str(code) + "&trusted=true"
        #print "Querying: " + url
        
        #c = pycurl.Curl()
        #c.setopt(c.URL, url)
        #try:
        #    c.setopt(c.WRITEDATA, buf)
        #except:
        #    c.setopt(c.WRITEFUNCTION, buf.write)
        #c.perform()
        #c.close()
        resp = requests.get(url,timeout=5)

        s = resp.text

        #print s
        
        if (s == "ENABLED"):
        	return code

        return ""
    except:
        return ""

parser = argparse.ArgumentParser(description="Manage ARDI Services")
parser.add_argument('server', help='The URL of the ARDI site')
parser.add_argument('addon', help='The name of the ARDI addon to be serviced')
parser.add_argument('mode', help='Install or remove the addon service')

args = parser.parse_args()
    
#Override
remotehost="localhost"
if args.server != None:
    remotehost = args.server

addon = args.addon
	
server = remotehost

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 confirmation of addon existance...
driver = GetAddonDetails(remotehost,addon)

if args.mode=="install" and driver == "":
    print("Addon not found on specified ARDI instance/site")
    sys.exit()

#print "Installing " + addon + " Addon Service(s)"

ext = "default"

ps = remotehost.rfind('/')
ext = remotehost[ps+1:]

print("Installing ardi-" + addon + "-" + ext + " for server @ " + server)

if True:
	if args.mode == "install":
		if platform.system() == "Windows":
			WindowsInstaller(addon,server,ext)
			pass
		else:
			LinuxInstaller(addon,server,ext)
			pass
			
	if args.mode == "remove":
		if platform.system() == "Windows":
			WindowsUninstaller(addon,server,ext)
			pass
		else:
			LinuxUninstaller(addon,server,ext)
			pass
		
print("ARDI Service Maintenance Complete")
