@echo off
SetLocal EnableExtensions EnableDelayedExpansion
echo The Inobitec DICOM Server ^(PACS^) update script

:enter_dest_dir
set DEST_DIR=
set /p DEST_DIR="Enter the path to Inobitec DICOM Server [C:\PACSServer]: "
if "!DEST_DIR!"=="" set "DEST_DIR=C:\PACSServer"
if not exist "!DEST_DIR!" (
  echo Prevous version of Inobitec DICOM Server ^(PACS^) is not found at location !DEST_DIR!
  goto enter_dest_dir
)

echo Stopping PACSServer...
sc stop PACSServer

echo Creating backup of prevous version...
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%"
set "fullstamp=!YYYY!-!MM!-!DD!_!HH!-!Min!-!Sec!"

rename "!DEST_DIR!\bin" "bin_bak_!fullstamp!"
if ERRORLEVEL 1 goto backup_failed
if exist "!DEST_DIR!\WebAdmin" (
  rename "!DEST_DIR!\WebAdmin" "WebAdmin_bak_!fullstamp!"
  if ERRORLEVEL 1 goto backup_failed
)

echo Copying files...
mkdir "!DEST_DIR!\bin"
if ERRORLEVEL 1 goto copying_failed
xcopy /E /Y ..\bin "!DEST_DIR!\bin"
if ERRORLEVEL 1 goto copying_failed

CALL :prev_version_is_old "!DEST_DIR!\bin_bak_!fullstamp!" , res
if "!res!" == "true" goto old_version 

:after_adding_dependency

echo Update Inobitec DICOM Server ^(PACS^) completed.
goto end

:update_ini
  set SETTING_FILE=%~1
  for /f "delims== eol=# tokens=1,*" %%i in (!SETTING_FILE!) do (
    set %%i=%%j
  )

  rename "!SETTING_FILE!" "srv_settings.ini_bak_!fullstamp!"

  @REM DB connection
  (echo database/conn_string=!conn_string!) >> "!SETTING_FILE!"
  if "!db_address!" neq "" ((echo database/address=!db_address!) >> "!SETTING_FILE!")
  if "!db_port!" neq "" ((echo database/port=!db_port!) >> "!SETTING_FILE!")
  if "!db_name!" neq "" ((echo database/name=!db_name!) >> "!SETTING_FILE!")
  (echo database/user=!user!) >> "!SETTING_FILE!"
  (echo database/pass=!pass!) >> "!SETTING_FILE!"
  if "!max_connections_number!" neq "" ((echo database/max_connections_number=!max_connections_number!) >> "!SETTING_FILE!")
  if "!driver_type!" neq "" (
    (echo database/driver=!driver_type!) >> "!SETTING_FILE!"
  ) else (
    (echo database/driver=%~3) >> "!SETTING_FILE!"
  )
  @REM HTTP Server
  if "!unsecure_http_service_port!" neq "" ((echo http_server/port=!unsecure_http_service_port!) >> "!SETTING_FILE!")
  if "!master_cookie!" neq "" ((echo http_server/master_cookie=!master_cookie!) >> "!SETTING_FILE!")
  if "!acceptable_address!" neq "" ((echo http_server/acceptable_address=!acceptable_address!) >> "!SETTING_FILE!")
  @REM Admin Web Console
  if "!web_admin_path!" neq "" ((echo web_admin/files_path=!web_admin_path!) >> "!SETTING_FILE!")
  (echo web_admin/login=!web_admin_login!) >> "!SETTING_FILE!"
  (echo web_admin/password=!web_admin_password!) >> "!SETTING_FILE!"
  (echo web_admin/session_timeout=!web_admin_session_life_time!) >> "!SETTING_FILE!"
  if "!font_path!" neq "" ((echo web_admin/font_path=!font_path!) >> "!SETTING_FILE!")
  @REM WADO
  if "!enable_wado_study_web_service!" neq "" ((echo wado/study_web_service/enabled=!enable_wado_study_web_service!) >> "!SETTING_FILE!")
  if "!wado_study_service_port!" neq "" ((echo wado/study_web_service/port=!wado_study_service_port!) >> "!SETTING_FILE!")
  @REM DICOM Services
  if "!activate_unsecure_dicom_store_service!" neq "" ((echo dicom/store_service/unsecure/enabled=!activate_unsecure_dicom_store_service!) >> "!SETTING_FILE!")
  if "!unsecure_dicom_store_service_port!" neq "" ((echo dicom/store_service/unsecure/port=!unsecure_dicom_store_service_port!) >> "!SETTING_FILE!")
  if "!activate_unsecure_dicom_mwl_service!" neq "" ((echo dicom/mwl_service/unsecure/enabled=!activate_unsecure_dicom_mwl_service!) >> "!SETTING_FILE!")
  if "!unsecure_dicom_mwl_service_port!" neq "" ((echo dicom/mwl_service/unsecure/port=!unsecure_dicom_mwl_service_port!) >> "!SETTING_FILE!")
  if "!activate_secure_dicom_store_service!" neq "" ((echo dicom/store_service/secure/enabled=!activate_secure_dicom_store_service!) >> "!SETTING_FILE!")
  if "!secure_dicom_store_service_port!" neq "" ((echo dicom/store_service/secure/port=!secure_dicom_store_service_port!) >> "!SETTING_FILE!")
  if "!activate_secure_dicom_mwl_service!" neq "" ((echo dicom/mwl_service/secure/enabled=!activate_secure_dicom_mwl_service!) >> "!SETTING_FILE!")
  if "!secure_dicom_mwl_service_port!" neq "" ((echo dicom/mwl_service/secure/port=!secure_dicom_mwl_service_port!) >> "!SETTING_FILE!")
  if "!pacs_server_ae_title!" neq "" ((echo dicom/ae_title=!pacs_server_ae_title!) >> "!SETTING_FILE!")
  if "!accept_association_from_any!" neq "" ((echo dicom/accept_unknown=!accept_association_from_any!) >> "!SETTING_FILE!")
  if "!strict_dicom_standard!" neq "" ((echo dicom/strict_standard=!strict_dicom_standard!) >> "!SETTING_FILE!")
  @REM Certificates
  if "!certs_path!" neq "" ((echo dicom/tls/certs_path=!certs_path!) >> "!SETTING_FILE!")
  if "!cert_trusted_dir_path!" neq "" ((echo dicom/tls/trusted_certs_path=!cert_trusted_dir_path!) >> "!SETTING_FILE!")
  if "!cert_client_private_path!" neq "" ((echo dicom/tls/scu_private_key=!cert_client_private_path!) >> "!SETTING_FILE!")
  if "!cert_client_public_path!" neq "" ((echo dicom/tls/scu_public_cert=!cert_client_public_path!) >> "!SETTING_FILE!")
  if "!cert_server_private_path!" neq "" ((echo dicom/tls/scp_private_key=!cert_server_private_path!) >> "!SETTING_FILE!")
  if "!cert_server_public_path!" neq "" ((echo dicom/tls/scp_public_cert=!cert_server_public_path!) >> "!SETTING_FILE!")
  @REM RIS
  if "!ris_notifying!" neq "" ((echo ris/notifications_enabled=!ris_notifying!) >> "!SETTING_FILE!")
  if "!ris_ip!" neq "" ((echo ris/address=!ris_ip!) >> "!SETTING_FILE!")
  if "!ris_port!" neq "" ((echo ris/port=!ris_port!) >> "!SETTING_FILE!")
  @REM Archiving
  (echo compression/level=!compression_level!) >> "!SETTING_FILE!"
  (echo compression/compress_after=!uncompressing_store_days!) >> "!SETTING_FILE!"
  @REM Connecting to a regional DICOM server
  if "!regional_pacs_enabled!" neq "" ((echo regional_pacs/enabled=!regional_pacs_enabled!) >> "!SETTING_FILE!")
  if "!regional_pacs_ae_title!" neq "" ((echo regional_pacs/ae_title=!regional_pacs_ae_title!) >> "!SETTING_FILE!")
  if "!regional_pacs_preferred_transfer_syntax!" neq "" ((echo regional_pacs/preferred_ts=!regional_pacs_preferred_transfer_syntax!) >> "!SETTING_FILE!")
  if "!regional_pacs_address!" neq "" ((echo regional_pacs/address=!regional_pacs_address!) >> "!SETTING_FILE!")
  if "!regional_pacs_port!" neq "" ((echo regional_pacs/port=!regional_pacs_port!) >> "!SETTING_FILE!")
  if "!regional_pacs_secured_connection!" neq "" ((echo regional_pacs/use_tls=!regional_pacs_secured_connection!) >> "!SETTING_FILE!")
  if "!regional_pacs_certificate_filename!" neq "" ((echo regional_pacs/cert_filename=!regional_pacs_certificate_filename!) >> "!SETTING_FILE!")
  if "!regional_pacs_extended_search!" neq "" ((echo regional_pacs/extended_search_enabled=!regional_pacs_extended_search!) >> "!SETTING_FILE!")
  if "!regional_pacs_storage_commitment_enabled!" neq "" ((echo regional_pacs/storage_commitment_enabled=!regional_pacs_storage_commitment_enabled!) >> "!SETTING_FILE!")
  if "!storage_commitment_time_interval!" neq "" ((echo regional_pacs/storage_commitment_interval=!storage_commitment_time_interval!) >> "!SETTING_FILE!")
  if "!regional_pacs_connection_timeout!" neq "" ((echo regional_pacs/connection_timeout=!regional_pacs_connection_timeout!) >> "!SETTING_FILE!")
  if "!regional_pacs_upload_timeout!" neq "" ((echo regional_pacs/upload_timeout=!regional_pacs_upload_timeout!) >> "!SETTING_FILE!")
  if "!regional_pacs_association_lifetime!" neq "" ((echo regional_pacs/association_timeout=!regional_pacs_association_lifetime!) >> "!SETTING_FILE!")
  @REM Removing old studies
  (echo autoremove/store_days=!store_days!) >> "!SETTING_FILE!"
  if "!enable_remove_old_series_by_storage!" neq "" ((echo autoremove/by_storage_enabled=!enable_remove_old_series_by_storage!) >> "!SETTING_FILE!")
  if "!confirm_remove_old_series_by_storage!" neq "" ((echo autoremove/by_storage_confirmed=!confirm_remove_old_series_by_storage!) >> "!SETTING_FILE!")
  if "!remove_old_series_by_storage_thresold!" neq "" ((echo autoremove/threshold=!remove_old_series_by_storage_thresold!) >> "!SETTING_FILE!")
  if "!remove_by_storage_not_uploaded!" neq "" ((echo autoremove/remove_not_uploaded_enabled=!remove_by_storage_not_uploaded!) >> "!SETTING_FILE!")
  @REM Service Threads
  if "!storage_worker_threads_count!" neq "" ((echo workers/thread_count=!storage_worker_threads_count!) >> "!SETTING_FILE!")
  if "!storage_worker_tasks_delay!" neq "" ((echo workers/delay=!storage_worker_tasks_delay!) >> "!SETTING_FILE!")
  if "!storage_worker_collect_compression_task_count!" neq "" ((echo workers/compression_task_count=!storage_worker_collect_compression_task_count!) >> "!SETTING_FILE!")
  if "!storage_worker_collect_remove_task_count!" neq "" ((echo workers/autoremove_task_count=!storage_worker_collect_remove_task_count!) >> "!SETTING_FILE!")
  if "!storage_worker_collect_upload_task_count!" neq "" ((echo workers/regional_pacs_task_count=!storage_worker_collect_upload_task_count!) >> "!SETTING_FILE!")
  if "!remove_old_series_by_storage_collect_task_count!" neq "" ((echo workers/autoremove_by_storage_task_count=!remove_old_series_by_storage_collect_task_count!) >> "!SETTING_FILE!")
  @REM Notifications
  if "!free_disk_space_warning_notify_limit!" neq "" ((echo notifications/storage_free_space_limit=!free_disk_space_warning_notify_limit!) >> "!SETTING_FILE!")
  @REM Series import
  if "!chunk_size!" neq "" ((echo import/chunk_size=!chunk_size!) >> "!SETTING_FILE!")
  if "!import_session_timeout!" neq "" ((echo import/session_timeout=!import_session_timeout!) >> "!SETTING_FILE!")
  @REM Research Storage
  if "!free_disk_space_limit!" neq "" ((echo storage/free_disk_space_limit=!free_disk_space_limit!) >> "!SETTING_FILE!")
  if "!disk_free_space_check_frequency!" neq "" ((echo storage/disk_free_space_check_frequency=!disk_free_space_check_frequency!) >> "!SETTING_FILE!")
  if "!dcm_temporary_folder!" neq "" ((echo storage/dcm_temporary_folder=!dcm_temporary_folder!) >> "!SETTING_FILE!")
  if "!crop_long_accession_number!" neq "" ((echo storage/crop_long_accession_number=!crop_long_accession_number!) >> "!SETTING_FILE!")
  if "!overwrite_image!" neq "" ((echo overwrite_image=!overwrite_image!) >> "!SETTING_FILE!")

  set enableTraceLoggerLevel=%enableTraceLoggerLevel: =%
  set result=false
  if "!enableTraceLoggerLevel!" == "true" set result=true
  if "!enableTraceLoggerLevel!" == "TRUE" set result=true
  set LOG_SETTING_FILE=%~2

  if exist !LOG_SETTING_FILE! (
    goto :log_exist
  ) else ( 
    if "!result!" == "true" ((echo logger/level=TRACE) >> "!SETTING_FILE!") & goto :end_log_exist
  )

  :log_exist
  for /f "delims== eol=# tokens=1,*" %%i in (!LOG_SETTING_FILE!) do (
    set %%i=%%j
  )
  set "level=%log4cpp.rootCategory:,=" & rem."%"
  set level=%level: =%
  if "!result!" == "true" (
    if "!level!" == "DEBUG" (
      set level=TRACE
      )
  )
  (echo logger/level=!level!) >> "!SETTING_FILE!"
  if "!log4cpp.appender.A1.fileName!" neq "" ((echo logger/files_path=%log4cpp.appender.A1.fileName:.=_%) >> "!SETTING_FILE!")
  if "!log4cpp.appender.A1.maxFileSize!" neq "" ((echo logger/max_file_size=!log4cpp.appender.A1.maxFileSize!) >> "!SETTING_FILE!")
  if "!log4cpp.appender.A1.maxBackupIndex!" neq "" ((echo logger/max_file_count=!log4cpp.appender.A1.maxBackupIndex!) >> "!SETTING_FILE!")
  :end_log_exist
EXIT /B 0

:prev_version_is_old
  set prog=%~1
  for /f "delims=" %%i in ('!prog!\pacs_server.exe -v') do (
    set command_res=%%i
  )
  set command_res=%command_res:(=%
  set command_res=%command_res:)=%
  for %%i in (!command_res!) do (
    for /f "delims=" %%l in ('echo %%i ^| findstr /r "[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*"') do (
        set version=%%l
      )
  )

  for /F "tokens=1,2,3 delims=." %%a in ("!version!") do (
    set Major=%%a
    set Minor=%%b
  )
  set %~2=false
  if !Major! leq 2 if !Minor! lss 9 set %~2=true
EXIT /B 0

:rename_with_replace
  set files_path=%~1
  set prev_name=%~2
  set new_name=%~3
  if exist "!files_path!\!new_name!" del "!files_path!\!new_name!" /s /f /q
  rename "!files_path!\!prev_name!" "!new_name!"
EXIT /B 0

:old_version
echo Update config...
set CONFIG_FILE=!DEST_DIR!\conf\srv_settings.ini
CALL :update_ini !CONFIG_FILE! , !DEST_DIR!\conf\log4cpp.ini , QPSQL EXIT /B !ERRORLEVEL!

echo Update service...

set SERVICE_NAME=
set /p SERVICE_NAME="Enter the Inobitec DICOM Server (PACS) service name [PACSServer]: "
if "!SERVICE_NAME!"=="" set "SERVICE_NAME=PACSServer"
sc stop !SERVICE_NAME!

sc delete !SERVICE_NAME!
if ERRORLEVEL 1 goto remove_service_failed

sc create !SERVICE_NAME! binPath= "!DEST_DIR!\bin\pacs_server.exe -cfg !CONFIG_FILE!" start= auto DisplayName= "Inobitec DICOM Server (PACS)"
if ERRORLEVEL 1 goto create_service_failed
choice /m "Add dependency from DBMS service?"
if not "!ERRORLEVEL!"=="1" goto after_adding_dependency

:enter_dbms_service_name
set DBMS_SERVICE_NAME=
set /p DBMS_SERVICE_NAME="Enter DBMS service name: "
if "!DBMS_SERVICE_NAME!"=="" (
  echo Skip adding DBMS service dependency.
  goto after_adding_dependency
)

sc config !SERVICE_NAME! depend= !DBMS_SERVICE_NAME!
if ERRORLEVEL 1 (
  echo Addin dependency failed. Is service !DBMS_SERVICE_NAME! exists?
  goto enter_dbms_service_name
)
goto after_adding_dependency

:backup_failed
echo Creating backup failed.
goto restore

:copying_failed
echo Copying new files failed.
goto restore

:remove_service_failed
echo Removing old service failed.
goto restore

:create_service_failed
echo Creating new service failed. The service has been disrupted.
goto restore

:restore
echo Restoring from backup...
if exist "!DEST_DIR!\bin" rd /S /Q "!DEST_DIR!\bin"
rename "!DEST_DIR!\bin_bak_!fullstamp!" bin
if exist "!DEST_DIR!\conf\srv_settings.ini_bak_!fullstamp!" CALL :rename_with_replace "!DEST_DIR!\conf" , "srv_settings.ini_bak_!fullstamp!" , "srv_settings.ini" EXIT /B !ERRORLEVEL!
if exist "!DEST_DIR!\WebAdmin_bak_!fullstamp!" rename "!DEST_DIR!\WebAdmin_bak_!fullstamp!" "WebAdmin"
goto failed

:failed
echo Update Inobitec DICOM Server ^(PACS^) failed.

:end
pause
