@echo off

rem ##############################################################################
rem #
rem # Copyright (c) 2013 VMware, Inc. All rights reserved.
rem # -- VMware Confidential
rem #
rem ##############################################################################

if "%PROGRAMDATA%"=="" (
   set "_VC_DATA_DIR=%ALLUSERSPROFILE%\Application Data\VMware\VMware VirtualCenter"
) else (
   set "_VC_DATA_DIR=%PROGRAMDATA%\VMware\VMware VirtualCenter"
)

set _VC_REG_KEY="HKLM\SOFTWARE\VMware, Inc.\VMware VirtualCenter"
set _VC_INSTALL_REG_KEY="HKLM\SOFTWARE\VMware, Inc.\VMware VirtualCenter\Install"
set _VC_REG_EXE=%windir%\system32\reg.exe
set _VC_INSTALL_DIR=
call :GetVCInstallDir > nul 2>&1
if "%_VC_INSTALL_DIR%"=="" (
   call :setLastErrorAndEcho "Failed to load the vCenter Server install path from the registry."
   exit /B 2
)

set _VC_LS_URL=
call :GetLSUrl > nul 2>&1
if "%_VC_LS_URL%"=="" (
   call :setLastErrorAndEcho "Failed to load the vCenter Server Lookup Service URL from the registry."
   exit /B 2
)

set _VC_IS_URL=
call :GetISUrl > nul 2>&1
if "%_VC_IS_URL%"=="" (
   call :setLastErrorAndEcho "Failed to load the vCenter Server Inventory Service URL from the registry."
   exit /B 2
)

set _VC_SERVER_HTTPS_PORT=
call :GetVCReverseProxyPort > nul 2>&1
if "%_VC_SERVER_HTTPS_PORT%"=="" (
   call :setLastErrorAndEcho "Failed to load the vCenter Server reverse proxy port from the registry."
   exit /B 2
)

set _VC_SERVER_FQDN=
call :GetVCFQDN > nul 2>&1
if "%_VC_SERVER_FQDN%"=="" (
   call :setLastErrorAndEcho "Failed to load the vCenter Server FQDN from the registry."
   exit /B 2
)

set "_VC_SERVER_URL=https://%_VC_SERVER_FQDN%:%_VC_SERVER_HTTPS_PORT%/sdk"
set "_VC_ISREGTOOL_DIR=%_VC_INSTALL_DIR%\isregtool"
set "_VC_REGISTER_IS_BAT=%_VC_ISREGTOOL_DIR%\register-is.bat"
set "_VC_ALT_REGISTER_IS_BAT=%_VC_ISREGTOOL_DIR%\alt-register-is.bat"
set "_VC_ALT_REGISTER_IS_BAT_SRC=%~dp0vcutils\alt-register-is.bat"

call "%~dp0common" Validating the input parameters...
if NOT EXIST "%_VC_INSTALL_DIR%" (
   call :setLastErrorAndEcho "Cannot find the vCenter Server Installation directory %_VC_INSTALL_DIR%"
   goto endInputError
)

if NOT EXIST "%_VC_REGISTER_IS_BAT%" (
   call :setLastErrorAndEcho "Cannot find the vCenter Server - Inventory Service registration script  %_VC_REGISTER_IS_BAT%"
   goto endInputError
)


call "%~dp0common" Registering vCenter with Inventory Service...

rem if vpxd.cfg has references to sso.crt and sso.key
rem and if vcsso.properties mentions sso.crt
rem and the VC SSL directory contains sso.crt, sso.key and sso.pfx
rem then use sso.crt for VC-IS registration. i.e., use alt-register-is.bat

FIND /I "%_VC_DATA_DIR%\SSL\sso.crt" "%_VC_DATA_DIR%\vpxd.cfg"
IF ERRORLEVEL 1 (
   call :setLastErrorAndEcho "Cannot find reference to sso.crt in vpxd.cfg %ERRORLEVEL%"
   goto regularRegistration
)

FIND /I "%_VC_DATA_DIR%\SSL\sso.key" "%_VC_DATA_DIR%\vpxd.cfg"
IF ERRORLEVEL 1 (
   call :setLastErrorAndEcho "Cannot find reference to sso.key in vpxd.cfg %ERRORLEVEL%"
   goto regularRegistration
)

if NOT EXIST "%_VC_INSTALL_DIR%\ssoregtool\vcsso.properties" (
   call :setLastErrorAndEcho "Cannot find the vCenter Server SSO properties %_VC_INSTALL_DIR%"
   goto regularRegistration
)

FIND /I "cert=%_VC_DATA_DIR%\SSL\sso.crt" "%_VC_INSTALL_DIR%\ssoregtool\vcsso.properties"
IF ERRORLEVEL 1 (
   call :setLastErrorAndEcho "Cannot find reference to sso.crt in vcsso.properties %ERRORLEVEL%"
   goto regularRegistration
)

if NOT EXIST "%_VC_DATA_DIR%\SSL\sso.crt" (
   call :setLastErrorAndEcho "Cannot find sso.crt in %_VC_DATA_DIR\SSL %_VC_INSTALL_DIR%"
   goto regularRegistration
)

if NOT EXIST "%_VC_DATA_DIR%\SSL\sso.key" (
   call :setLastErrorAndEcho "Cannot find sso.key in %_VC_DATA_DIR\SSL %_VC_INSTALL_DIR%"
   goto regularRegistration
)

if NOT EXIST "%_VC_DATA_DIR%\SSL\sso.pfx" (
   call :setLastErrorAndEcho "Cannot find sso.pfx in %_VC_DATA_DIR\SSL %_VC_INSTALL_DIR%"
   goto regularRegistration
)

rem if we got here, there is a good possibility that we need to use
rem alt-register-is.bat for VC-IS registration.

:alternateRegistration
call :setLastErrorAndEcho "Copying %_VC_ALT_REGISTER_IS_BAT_SRC% to %_VC_ALT_REGISTER_IS_BAT%"
copy /v /y "%_VC_ALT_REGISTER_IS_BAT_SRC%" "%_VC_ALT_REGISTER_IS_BAT%"
call :registerVCIS "%_VC_ALT_REGISTER_IS_BAT%"
if ERRORLEVEL 1 (
   del /q "%_VC_ALT_REGISTER_IS_BAT%" > nul 2> nul
   goto endError
)
call :setLastErrorAndEcho "Deleting %_VC_ALT_REGISTER_IS_BAT%"
del /q "%_VC_ALT_REGISTER_IS_BAT%" > nul 2> nul
goto doneRegistration

rem if we did not find sso.crt or its references then proceed with the usual
rem registration
:regularRegistration
call :registerVCIS "%_VC_REGISTER_IS_BAT%"
if ERRORLEVEL 1 (
   goto endError
)

:doneRegistration

call "%~dp0common" Setup complete. Restarting services...
call "%~dp0common" Restarting vCenter Server...
echo "Restarting services... (This can take some time)" 1>&2

sc stop vctomcat

rem stopping and starting vcenter services can take some time. Arbitrarily wait
rem 300 seconds before declaring failure.
rem
rem Note: sc query <service> | FIND ": 1  STOPPED "
rem Since there is no effective way to wait for a service to stop and start and
rem testing for errorlevel is getting tricky, I've chosed to search for the
rem string like ": 1  STOPPED" and ": 4  RUNNING" which are fairly unique and
rem locale agnostic.

set loopCount=0

call "%~dp0common" Stopping vCenter Web Services...
echo "Stopping vCenter Web Services..." 1>&2

:stopVctomcat
set /a loopCount=loopCount+1
sc query vctomcat | FIND ": 1  STOPPED "
if ERRORLEVEL 1 (
   call :setLastErrorAndEcho "Cannot stop the vCenter Server Web Services: %ERRORLEVEL%"
   timeout /t 5 /nobreak > nul
   if %loopCount% GTR 60 goto endError
   goto stopVctomcat
)

sc stop vpxd

set loopCount=0
call "%~dp0common" Stopping vCenter Server...
echo "Stopping vCenter Server..." 1>&2

:stopVpxd
set /a loopCount=loopCount+1
sc query vpxd | FIND ": 1  STOPPED "
if ERRORLEVEL 1 (
   call :setLastErrorAndEcho "Cannot stop vCenter Server: %ERRORLEVEL%"
   timeout /t 5 /nobreak > nul
   if %loopCount% GTR 60 goto endError
   goto stopVpxd
)

sc start vpxd

set loopCount=0
call "%~dp0common" Starting vCenter Server...
echo "Starting vCenter Server and other services..." 1>&2

:startVpxd
set /a loopCount=loopCount+1
sc query vpxd | FIND ": 4  RUNNING "
if ERRORLEVEL 1 (
   call :setLastErrorAndEcho "Cannot start vCenter Server: %ERRORLEVEL%"
   timeout /t 5 /nobreak > nul
   if %loopCount% GTR 60 goto endError
   goto startVpxd
)

sc start vctomcat
if ERRORLEVEL 1 (
   call :setLastErrorAndEcho "Cannot start vCenter Server Web Services: %ERRORLEVEL%"
   goto endError
)

set loopCount=0
call "%~dp0common" Restarting vSphere Profile-Driven Storage Service...
sc stop vimPBSM

:stopVimPBSM
set /a loopCount=loopCount+1
sc query vimPBSM | FIND ": 1  STOPPED "
if ERRORLEVEL 1 (
   call :setLastErrorAndEcho "Cannot stop vSphere Profile-Driven Storage Service: %ERRORLEVEL%"
   timeout /t 5 /nobreak > nul
   if %loopCount% GTR 60 goto endError
   goto stopVimPBSM
)

sc start vimPBSM
if ERRORLEVEL 1 (
   call :setLastErrorAndEcho "Cannot start vCenter Profile-Driven Storage Service: %ERRORLEVEL%"
   goto endError
)


:end
call "%~dp0common" Successfully updated the vCenter Server trust to Inventory Service
exit /B 0


:GetVCInstallDir
set _VC_INSTALL_DIR=
for /F "usebackq tokens=1,2*" %%i in (`%_VC_REG_EXE% query %_VC_REG_KEY% /v "InstallPath"`) DO (
   if "%%i"=="InstallPath" (
      SET "_VC_INSTALL_DIR=%%k"
   )
)
exit /B 0


:GetISUrl
set _VC_IS_URL=
for /F "usebackq tokens=1,2*" %%i in (`%_VC_REG_EXE% query %_VC_INSTALL_REG_KEY% /v "IsUrl"`) DO (
   if "%%i"=="IsUrl" (
      SET "_VC_IS_URL=%%k"
   )
)
exit /B 0


:GetLSUrl
set _VC_LS_URL=
for /F "usebackq tokens=1,2*" %%i in (`%_VC_REG_EXE% query %_VC_INSTALL_REG_KEY% /v "LsUrl"`) DO (
   if "%%i"=="LsUrl" (
      SET "_VC_LS_URL=%%k"
   )
)
exit /B 0


:GetVCReverseProxyPort
set _VC_SERVER_HTTPS_PORT=
for /F "usebackq tokens=1,2*" %%i in (`%_VC_REG_EXE% query %_VC_REG_KEY% /v "HttpsProxyPort"`) DO (
   if "%%i"=="HttpsProxyPort" (
      SET "_VC_SERVER_HTTPS_PORT=%%k"
   )
)
exit /B 0

:GetVCFQDN
set _VC_SERVER_FQDN=
for /F "usebackq tokens=1,2*" %%i in (`%_VC_REG_EXE% query %_VC_REG_KEY% /v "FullyQualifiedDomainName"`) DO (
   if "%%i"=="FullyQualifiedDomainName" (
      SET "_VC_SERVER_FQDN=%%k"
   )
)
exit /B 0

:endError
call "%~dp0common" Updating the vCenter Server trust to Inventory Service failed.
exit /B 1

:endInputError
call "%~dp0common" Invalid input parameters specified. The vCenter Inventory Service trust update failed.
exit /B 3

:setLastErrorAndEcho
set last_error=%1
call "%~dp0common" "%last_error%"
exit /B 0

:registerVCIS
pushd %_VC_ISREGTOOL_DIR%
call %1 "%_VC_SERVER_URL%" "%_VC_IS_URL%" "%_VC_LS_URL%"
rem TODO find out about register-is.bat and its return codes
if ERRORLEVEL 1 (
   call :setLastErrorAndEcho "Cannot register vCenter with Inventory Service: %ERRORLEVEL%"
   popd
   exit /B 1
)
popd
exit /B 0

call "%~dp0common" Successfully updated the vCenter Server Trust to Inventory Service
