import ctypes
import os
import ssl
import subprocess
import urllib2
from datetime import datetime
from datetime import timedelta

msiLnk = itsm.getParameter('msiLnk')
Password = itsm.getParameter('PASS')


class disable_file_system_redirection():
    _disable = ctypes.windll.kernel32.Wow64DisableWow64FsRedirection
    _revert = ctypes.windll.kernel32.Wow64RevertWow64FsRedirection

    def __enter__(self):
        self.old_value = ctypes.c_long()
        self.success = self._disable(ctypes.byref(self.old_value))

    def __exit__(self, type, value, traceback):
        if self.success:
            self._revert(self.old_value)


with disable_file_system_redirection():
    username = os.path.basename(os.popen(r'whoami').read()).replace('\n', '')
    sid = os.popen(r'wmic useraccount where name="' + username + r'" get sid').read().splitlines()[1].strip()


def ExecuteCmd(cmd):
    with disable_file_system_redirection():
        obj = subprocess.Popen(["powershell", cmd], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        out, err = obj.communicate()
        return out, err


def Download(src_path, DURL):
    filepath = os.path.join(src_path, os.path.basename(DURL))
    request = urllib2.Request(DURL, headers={'User-Agent': "Magic Browser"})
    try:
        gcontext = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
        parsed = urllib2.urlopen(request, context=gcontext)
    except:
        parsed = urllib2.urlopen(request)
    if not os.path.exists(src_path):
        os.makedirs(src_path)
    with open(filepath, 'wb') as f:
        while True:
            chunk = parsed.read(100 * 1000 * 1000)
            if chunk:
                f.write(chunk)
            else:
                break
    return filepath


def CreateScriptFile(ps_content):
    try:
        file_name = 'ScriptFile.ps1'
        file_path = os.path.join(os.environ['TEMP'], file_name)
        with open(file_path, 'wb') as wr:
            wr.write(ps_content)
            wr.close()
        return file_path
    except:
        return None


def setTakSchXml(psCommand, minTs, TaskName):
    Current_time = datetime.now()
    Date = datetime.strftime(Current_time, "%Y-%m-%d")
    TimeForTask = Current_time + timedelta(seconds=(60 * minTs))
    Time = datetime.strftime(TimeForTask, "%H:%M:%S")
    XML = r'''<?xml version="1.0" encoding="UTF-16"?>
        <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
          <Triggers>
            <TimeTrigger>
        ''' + '      <StartBoundary>' + Date + 'T' + Time + '</StartBoundary>' + '''
              <Enabled>true</Enabled>
            </TimeTrigger>
          </Triggers>
          <Principals>
            <Principal id="Author">
              <UserId>''' + sid + r'''</UserId>
              <RunLevel>HighestAvailable</RunLevel>
            </Principal>
          </Principals>
          <Settings>
            <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
            <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
            <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
            <AllowHardTerminate>true</AllowHardTerminate>
            <StartWhenAvailable>false</StartWhenAvailable>
            <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
            <IdleSettings>
              <StopOnIdleEnd>true</StopOnIdleEnd>
              <RestartOnIdle>false</RestartOnIdle>
            </IdleSettings>
            <AllowStartOnDemand>true</AllowStartOnDemand>
            <Enabled>true</Enabled>
            <Hidden>false</Hidden>
            <RunOnlyIfIdle>false</RunOnlyIfIdle>
            <WakeToRun>false</WakeToRun>
            <ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
            <Priority>7</Priority>
          </Settings>
          <Actions Context="Author">
            <Exec>
                <Command>powershell</Command>
                <Arguments>''' + psCommand + r'''</Arguments>
            </Exec>
            <Exec>
                <Command>schtasks</Command>
                <Arguments>/delete /TN "''' + TaskName + r'''" /f</Arguments>
            </Exec>
          </Actions>
        </Task>'''

    ConfigPath = r"C:\Windows\temp\TaskXMLConfig.xml"
    with open(ConfigPath, "w") as xmlFile:
        xmlFile.write(XML)
        xmlFile.close()

    cmd = r'schtasks /create /tn "' + TaskName + r'" /XML ' + '"' + ConfigPath + '"'
    if os.path.exists(ConfigPath):
        result = ExecuteCmd(cmd)
        os.remove(ConfigPath)
        if result[0] != '':
            print result[0]
            return True
        else:
            print result[1]


arch = os.popen("wmic os get OSArchitecture").read()
if '64' in arch:
    URL = "https://download.comodo.com/cis/download/installs/ciscleanuptool/ciscleanuptool_x64.exe"
else:
    URL = "https://download.comodo.com/cis/download/installs/ciscleanuptool/ciscleanuptool_x86.exe"

itsMpath = ExecuteCmd(r'(Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\ITSMService -Name '
                      r'"ImagePath").ImagePath')[0].replace('"', '').replace('ITSMService.exe', 'cdm.db').replace(
    "\r\n", "")
src_path = os.environ['Temp']

SecTask = r'''
Get-Service ITSMService | Stop-Service
$StopService = Get-Service ITSMService | Select-Object Status
if ($StopService -match '.+Stopped') {
    Copy-Item -Path "''' + src_path + r'''\cdm.db" -Destination "''' + os.path.dirname(itsMpath) + r'''"
    Remove-Item -Path "''' + src_path + r'''\cdm.db"
    Remove-Item -Path "''' + src_path + r'''\%s"
    Remove-Item -Path "''' % os.path.basename(URL) + src_path + r'''\%s"
    Get-Service ITSMService | Start-Service        
}
''' % os.path.basename(msiLnk)

ScriptPath = CreateScriptFile(SecTask)

exePath = Download(src_path, URL)

if os.path.exists(exePath):
    Backup = r'Copy-Item -Path "' + itsMpath + r'" -Destination "' + src_path + r'"'
    if os.path.exists(itsMpath):
        ExecuteCmd(Backup)
        if os.path.exists(src_path + r'\cdm.db'):
            print "Backup created [cdm.db]\n"
            msiPath = Download(src_path, msiLnk)
            if os.path.exists(msiPath):
                if setTakSchXml(r'msiexec /quiet /i "' + msiPath + '"', 10, 'InstalMsi'):
                    if setTakSchXml(ScriptPath, 15, 'RestoreCdmDb'):
                        subprocess.Popen(exePath + r' -silent -ccconly -password "' + Password + '"')
                        print 'Script executed successfully'
                    else:
                        print "Task schedule failed [RestoreCdmDb]"
                else:
                    print "Task schedule failed [InstallMsi]"
            else:
                print "Download failed [" + msiLnk + "]"
        else:
            print "Backup failed"
    else:
        print 'ITSM service does not exists'
else:
    print "Download failed"
