Option Explicit
On Error Resume Next

Include "pva-agent-helper.vbs"

' This constant is replaced by the build system. In the result script this bool value will reflect 
' the configfuration of the PVA core. If PVA_MN_CORE is 1, then we work for PVA management node core,
' otherwise the core we deal with is for slave agent.    
const PVA_MN_CORE=0' 1

' Define constants
const MSSQL_REG_LOGINMODE = "\MsSqlServer\LoginMode"
Dim MSSQL_REG_INSTANCE_ID
MSSQL_REG_INSTANCE_ID = "Instance Names\SQL\" & PVA_SQL_INSTANCE_NAME

' Create vzagent password
Dim agentSQLUserPassword
agentSQLUserPassword = CreateWindowsGUID & "aew7aR8we5raes:iu4Q!"

ParseCommandLine

REPLACE_PATTERN = agentSQLUserPassword

LogProgress "Starting PVA core postinstall configuration"

' Get paths
Dim agentInstallFolder, agentDataFolder, agentLogFolder
agentInstallFolder = SafeGetInstallDir(PVA_MN_CORE)
agentDataFolder = SafeGetDataDir(PVA_MN_CORE)
agentLogFolder = GetLogDir(PVA_MN_CORE)

CheckPrerequisites

EnableDrWatson

Dim PVA_PSTORAGE_DIR, PVA_TMP_DIR, PVA_ETC_DIR, PVA_DB_SCRIPTS_DIR
Dim PVA_AGENT_CONF, PVA_DATABASE_CONF, PVA_CMDLINE_CONF, PVA_XMLMAN_EXE
PVA_PSTORAGE_DIR = agentDataFolder & "\.pstorage"
PVA_TMP_DIR = agentDataFolder & "\tmp"
PVA_ETC_DIR = GetEtcDir(PVA_MN_CORE)
PVA_DB_SCRIPTS_DIR = agentInstallFolder & "\db"
PVA_AGENT_CONF = PVA_ETC_DIR & "\vzagent.conf"
PVA_DATABASE_CONF = PVA_ETC_DIR & "\database.conf"
PVA_XMLMAN_EXE = GetBinDir(PVA_MN_CORE) & "\vzlxmlman.exe"

' Create EID for hardware node
Dim EID
EID = GetPVAEID

CreateAgentCommandLine
UpdatePluginsVocs

If PVA_MN_CORE = 1 Then
	ConfigureAgentDataFolder
	ConfigureSQLServer
	ExecAllSQLScripts
	ConfigureMnService
Else
	If GetVzClusterState <> PVA_CS_STANDBY Then
		ConfigureAgentDataFolder
		ConfigureSQLite
		ConfigureAgentService
		RegisterMasterAfterUpgrade
	Else
		ConfigureAgentService
	End If
End If
EnableLogRotation(PVA_MN_CORE)

LogProgress "PVA core postinstall configuration finished succesfully"

If Err.number = 0 Then
	LogProgress Wscript.ScriptName & " finished succesfully"
	WScript.Quit 0
Else
	FailedQuitErr "Failed to execute PVA core posinstall configuration script"
End If

'
' Functions
'
Sub CheckPrerequisites
	LogProgress "Checking installation prerequisites"
	
	If agentInstallFolder = "" or agentDataFolder = "" Then FailedQuit "Can not find agent installation path in registry."
	
	If PVA_MN_CORE = 1 And Not IsSQLInstalled Then
		FailedQuit "SQL is not installed or configured properly. Can not continue hardware node configuration."
	End If
End Sub

Sub CreateAgentCommandLine
	' Create config for agent 
	GenerateServiceStartUpFile(PVA_MN_CORE)
End Sub

' Create/Modify config files and place them into required folders
Sub ConfigureAgentDataFolder
	
	LogProgress	"Creating PVA Agent configuration files"

	' Delete old folders, leaving folder ExportData
	LogProgress "Removing old data folders"
	DeleteFolderSafe PVA_PSTORAGE_DIR
	DeleteFolderSafe PVA_TMP_DIR
	DeleteFolderSafe PVA_ETC_DIR
	DeleteFolderSafe agentLogFolder

	' Copy config files to Data folder
	LogProgress "Creating new data folders"
	CreateFolderRecursive agentDataFolder
	CreateFolder PVA_PSTORAGE_DIR
	CreateFolder PVA_TMP_DIR
	CreateFolder PVA_ETC_DIR
	CreateFolderRecursive agentLogFolder
	CopyFolder agentInstallFolder & "\etc", PVA_ETC_DIR
	
	' Modify folder permissions
	RunCommand "%COMSPEC% /c echo Y| cacls """ & PVA_PSTORAGE_DIR & """" & " /G """ & GetAdministratorsGroupName & """:F"
	
	' Update config files with EID
	LogProgress "Storing EID in vzagent.conf"
	RunCommand """" & PVA_XMLMAN_EXE & """ -s " & EID & " -i data/system/configuration/id """ & PVA_AGENT_CONF & """"
	
	' Updating vzagent.conf
	UpdateAgentConf

	' Save CONFIGDIR in registry
	WriteRegistryKey GetRegistryKey & "CONFIGDIR", agentDataFolder

	' Save SQL address
	If PVA_MN_CORE = 1 Then
		ReplaceInFile PVA_DATABASE_CONF, "pvasqlserveraddress", PVA_SQL_SERVER_NAME
		ReplaceInFile PVA_DATABASE_CONF, "root", ""
	End If

	Dim encodedStr
	encodedStr = Base64Encode("sa" & vbLf & agentSQLUserPassword)
	WriteToFile PVA_PSTORAGE_DIR & "\" & PVA_SQL_USER, encodedStr	
	WriteToFile PVA_PSTORAGE_DIR & "\EID", EID	
	ReplaceInFile PVA_AGENT_CONF, DEFAULT_EID, EID
	
	Dim tcpPort, sslPort
	If PVA_MN_CORE = 1 Then
		tcpPort = PVA_TCP_PORT_MASTER
		sslPort = PVA_SSL_PORT_MASTER
	Else
		tcpPort = PVA_TCP_PORT_SLAVE
		sslPort = PVA_SSL_PORT_SLAVE
	End If
	ReplaceInFile PVA_AGENT_CONF, PVA_TCP_PORT_PLACEHOLDER, tcpPort
	ReplaceInFile PVA_AGENT_CONF, PVA_SSL_PORT_PLACEHOLDER, sslPort
End Sub

Sub UpdateAgentConf
	Dim fso, pluginsFolder, folder, file
	Set fso = CreateObject("Scripting.FileSystemObject")
	
	Set pluginsFolder = fso.GetFolder(agentInstallFolder & "\plugins")
	For Each folder In pluginsFolder.SubFolders
		For Each file In folder.Files
			If Right(file.Name, 5) = ".conf" Then
				RunCommand """" & GetBinDir(PVA_MN_CORE) & "\vzlconf_update.exe"" " &  _
							"""" & PVA_ETC_DIR & "\vzagent.conf"" " & _
							"""" & agentInstallFolder & "\plugins\" & folder.name & "\" & file.Name & """ " & _ 
							"""" & PVA_ETC_DIR & "\vzagent.conf"" "
			End If
		Next
	Next
End Sub

Sub UpdatePluginsVocs()
	LogProgress "Start generating vocabularies"
	SetupArchVocabulary agentInstallFolder, "create"
	LogProgress "Finish generating vocabularies"
End Sub

Sub ConfigureSQLite()
	LogProgress "Configuring SQLite..."
End Sub

Sub ExecAllSQLScripts()
	LogProgress "Reading sql scripts list"
	Dim filesListText
	filesListText = ReadFromFile(PVA_DB_SCRIPTS_DIR & "\sql_scripts.list")
	Dim filesList
	filesList = Split(filesListText, vbCrLf)

	Dim fileName
	For Each fileName In filesList
		If fileName <> "" Then
			ExecSQL PVA_DB_SCRIPTS_DIR & "\" & fileName
		End If
	Next
End Sub

Sub ExecSQL(sqlscript)
	LogProgress "Executing SQL script " & sqlscript
	ReplaceInFileEx sqlscript, sqlscript & ".tmp", DEFAULT_EID, EID
	RunCommand GetMSSqlPath & " -S" & PVA_SQL_SERVER_NAME & " -E -b -l 120 -i """ & sqlscript & ".tmp"""
End Sub

Sub ConfigureSQLServer()
	LogProgress "Configuring SQL Server"

	Dim err, out, ret

	If Not IsValidSQLLoginMode Then 
		StopService PVA_SQL_SERVICE_NAME
		WScript.Sleep 5000

		WriteRegistryKeyEx GetSQLLoginModePath, 2, "REG_DWORD"
	End If
	
	'Starting MS SQL service
	StartService PVA_SQL_SERVICE_NAME
	
	'Change password for 'sa' user, ignore 
	ret = ExecProgram(GetMSSqlPath & " -S" & PVA_SQL_SERVER_NAME & " -E -l 120 -b -r -Q ""sp_password @new='" & agentSQLUserPassword & _
		"', @loginame='sa'""", "", out, err)
	If ret <> 0 Then FailedQuitEx ret, "Failed to change password for sa SQL user - " & out & err

	'Turn on adavanced options	
	ret = ExecProgram(GetMSSqlPath & " -S" & PVA_SQL_SERVER_NAME & " -E -l 120 -b -r -Q ""sp_configure 'show advanced options', 1""", "", out, err)
	If ret <> 0 Then FailedQuitEx ret, "Failed to turn on advanced MSDE options - " & out & err
	
	'Install advanced options
	ret = ExecProgram(GetMSSqlPath & " -S" & PVA_SQL_SERVER_NAME & " -E -l 120 -b -r -Q ""reconfigure""", "", out, err)
	If ret <> 0 Then FailedQuitEx ret, "Failed to install advanced MSDE options - " & out & err
	
	'Set memory limit
	ret = ExecProgram(GetMSSqlPath & " -S" & PVA_SQL_SERVER_NAME & " -E -l 120 -b -r -Q ""sp_configure 'max server memory (MB)',50""", "", out, err)
	If ret <> 0 Then FailedQuitEx ret, "Failed to set MSDE memory limit - " & out & err
	
	'Install memory limit
	ret = ExecProgram(GetMSSqlPath & " -S" & PVA_SQL_SERVER_NAME & " -E -l 120 -b -r -Q ""reconfigure""", "", out, err)
	If ret <> 0 Then FailedQuitEx ret, "Failed to install MSDE memory limit - " & out & err
	
End Sub

Function GetSQLLoginModePath
	Dim value
	ReadRegistryKey GetSQLRegKey & MSSQL_REG_INSTANCE_ID, value
	GetSQLLoginModePath = GetSQLRegKey & value & MSSQL_REG_LOGINMODE
End Function

Function IsValidSQLLoginMode
	Dim value
	IsValidSQLLoginMode = ReadRegistryKey(GetSQLLoginModePath, value) <> 1 And value = 2
End Function

Sub ConfigureMnService
	LogProgress "Configuring service"
	StopService PVA_SERVICE_NAME_MASTER
	EnableFirewallBypass GetAgentBinary, "PVA Management Server 4.6"
	RegisterService PVA_SERVICE_NAME_MASTER, PVA_DISPLAY_SERVICE_NAME_MASTER, PVA_SERVICE_DESCRIPTION_MASTER, _
		GetAgentBinary() & " " & GetServiceStartUpFileName, Null, Null, Array(PVA_SQL_SERVICE_NAME)
	StartService PVA_SERVICE_NAME_MASTER
End Sub

Sub ConfigureAgentService
	LogProgress "Configuring service"
	EnableFirewallBypass GetAgentBinary, "PVA Agent 4.6"
	RegisterAgentService Null
End Sub

Sub RegisterMasterAfterUpgrade()
	LogProgress "Trying to register master after upgrade from 4.0"
	Dim fso, pathToMasterLogin
	Set fso = CreateObject("Scripting.FileSystemObject")
	pathToMasterLogin = GetTempFolder() & "\" & PVA_40_45_UPGRADE_FOLDER & "\.pstorage\master"

	If fso.FileExists(pathToMasterLogin) Then
		RunCommand GetBinDir(PVA_MN_CORE) & "\vzlInstallHelper.exe postUpgrade """ & GetTempFolder() & "\" & PVA_40_45_UPGRADE_FOLDER & """"
	Else
		LogProgress "Skipping upgrade 4.0->4.6: failed to find " & pathToMasterLogin
	End If
End Sub


Function GetPVAEID
	If PVA_MN_CORE = 1 Then
		GetPVAEID = CreateWindowsGUID()
	Else
		Dim out, err, ret
		ret = ExecProgram("""" & PVA_XMLMAN_EXE & """ -g data/system/configuration/id " & GetTempFolder() & "\" & PVA_40_45_UPGRADE_FOLDER & "\etc\vzagent.conf", "", out, err)
		If ret = 0 Then
			GetPVAEID = out
		Else
			GetPVAEID = CreateWindowsGUID()
		End If
	End If
End Function

Function CreateWindowsGUID()
  CreateWindowsGUID = CreateGUID(8) & "-" & _
    CreateGUID(4) & "-" & _
    CreateGUID(4) & "-" & _
    CreateGUID(4) & "-" & _
    CreateGUID(12)
End Function

Function CreateGUID(tmpLength)
  Randomize Timer
  Dim tmpCounter,tmpGUID
  Const strValid = "0123456789ABCDEF"
  For tmpCounter = 1 To tmpLength
    tmpGUID = tmpGUID & Mid(strValid, Int(Rnd(1) * Len(strValid)) + 1, 1)
  Next
  CreateGUID = tmpGUID
End Function

' Get arguments
Sub ParseCommandLine()
	If WScript.Arguments.Count() > 0 Then
		Dim i
		For i=0 To WScript.Arguments.Count()
			Select Case WScript.Arguments(i)
				Case "--debug"
					LogProgress "Debug output is enabled"
					DEBUG_OUTPUT = 1
				Case "--eid"
					If i = WScript.Arguments.Count() Then
						FailedQuit "Incorrect arguments - missing EID"
					End If
					i = i + 1
					EID = WScript.Arguments(i)
				Case "--password"
					If PVA_MN_CORE = 1 Then FailedQuit "SQL password should not be specified for Management Server installation"
					If i = WScript.Arguments.Count() Then
						FailedQuit "Incorrect arguments - missing password"
					End If
					i = i + 1
					agentSQLUserPassword = WScript.Arguments(i)
			End Select
		Next
	End If
End Sub
	
Sub EnableDrWatson
	WriteRegistryKey "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger", "drwtsn32 -p %ld -e %ld -g"
	WriteRegistryKey "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\Auto", "1"
	WriteRegistryKeyEx "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DrWatson\CreateCrashDump", 1, "REG_DWORD"
	WriteRegistryKeyEx "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DrWatson\CrashDumpType", 2, "REG_DWORD"
	WriteRegistryKeyEx "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DrWatson\VisualNotification", 1, "REG_DWORD"
	WriteRegistryKeyEx "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DrWatson\DumpAllThreads", 1, "REG_DWORD"
End Sub

' Include vzlVBLib.vbs
Sub Include(cNameScript)
	On Error Resume Next
	Dim oFS, oFile
	
	cNameScript = Mid(Wscript.ScriptFullName, 1, InStrRev(Wscript.ScriptFullName, "\")) & cNameScript
	
	Set oFS = CreateObject("Scripting.Filesystemobject")
	
	Set oFile = oFS.OpenTextFile(cNameScript)
	If Err.number <> 0 Then
		WScript.Echo "Failed to open include file '" & cNameScript & "' - " & Err.source & ", " & Err.Description
		WScript.Quit(-1)
	End If
	
	ExecuteGlobal oFile.ReadAll()
	If Err.number <> 0 Then
		WScript.Echo "Failed to ExecuteGlobal include file '" & cNameScript & "' - " & Err.source & ", " & Err.Description
		WScript.Quit(-1)
	End If

	oFile.Close
End Sub
