<#	
	.NOTES
	===========================================================================
	 Created with: 	SAPIEN Technologies, Inc., PowerShell Studio 2019 v5.6.157
	 Created on:   	3/14/2025 12:29 PM
	 Created by:   	danielc
	 Organization: 	
	 Filename:     	
	===========================================================================
	.DESCRIPTION
		A description of the file.
#>

function Start-IISAppRemote
{
	param (
		[string]$RemoteServer = "KCI-APP01",
		# Remote machine name or IP

		[string]$AppPoolName = "Tracking",
		[string]$SiteName = "Tracking",
		# Optional username
		[string]$CredentialUser = "",
		[securestring]$CredentialPassword # Optional password
	)
	
	# Create credentials if username and password are provided
	if ($CredentialUser -and $CredentialPassword)
	{
		$Credential = New-Object System.Management.Automation.PSCredential ($CredentialUser, $CredentialPassword)
	}
	else
	{
		$Credential = $null
	}
	
	# Define script block for remote execution
	$ScriptBlock = {
		param ($AppPoolName,
			$SiteName)
		
		Import-Module WebAdministration -ErrorAction Stop
		
		Write-Host "Starting IIS Application Pool: $AppPoolName"
		if ((Get-WebAppPoolState -Name $AppPoolName).Value -ne "Started")
		{
			Start-WebAppPool -Name $AppPoolName
			Write-Host "Application Pool '$AppPoolName' started successfully."
		}
		else
		{
			Write-Host "Application Pool '$AppPoolName' is already running."
		}
		
		Write-Host "Starting IIS Site: $SiteName"
		if ((Get-WebSiteState -Name $SiteName).Value -ne "Started")
		{
			Start-WebSite -Name $SiteName
			Write-Host "IIS Site '$SiteName' started successfully."
		}
		else
		{
			Write-Host "IIS Site '$SiteName' is already running."
		}
	}
	
	# Execute on remote server
	if ($Credential)
	{
		Invoke-Command -ComputerName $RemoteServer -Credential $Credential -ScriptBlock $ScriptBlock -ArgumentList $AppPoolName, $SiteName
	}
	else
	{
		Invoke-Command -ComputerName $RemoteServer -ScriptBlock $ScriptBlock -ArgumentList $AppPoolName, $SiteName
	}
}


function Deploy-ZipRemote
{
	param (
		[string]$RemoteServer = "KCI-APP01",
		# Remote machine name or IP

		[string]$TransferFolder = "\\KCI-SYN-CL01\PC Transfer\",
		# Local folder containing zip

		[string]$RemoteDeployPath = "C:\inetpub\tracking\",
		# Remote target path

		[string]$ZipFileName = "zzip.zip",
		[string]$CredentialUser = "",
		[securestring]$CredentialPassword
	)
	
	# Create credentials if provided
	if ($CredentialUser -and $CredentialPassword)
	{
		$Credential = New-Object System.Management.Automation.PSCredential ($CredentialUser, $CredentialPassword)
	}
	else
	{
		$Credential = $null
	}
	
	$LocalZipPath = Join-Path -Path $TransferFolder -ChildPath $ZipFileName
	$RemoteZipPath = Join-Path -Path $RemoteDeployPath -ChildPath $ZipFileName
	
	Write-Host "Copying ZIP file to remote server..."
	
	# Copy ZIP file using PowerShell Remoting (or direct UNC path if available)
	if ($Credential)
	{
		Copy-Item -Path $LocalZipPath -Destination "\\$RemoteServer\$($RemoteDeployPath.Replace(':', '$'))" -Credential $Credential -Force
	}
	else
	{
		Copy-Item -Path $LocalZipPath -Destination "\\$RemoteServer\$($RemoteDeployPath.Replace(':', '$'))" -Force
	}
	
	Write-Host "Extracting ZIP file on remote server..."
	
	# Run the extraction on the remote machine
	$ScriptBlock = {
		param ($RemoteZipPath,
			$RemoteDeployPath)
		
		if (-Not (Test-Path $RemoteZipPath))
		{
			Write-Host "Error: ZIP file not found at $RemoteZipPath"
			return
		}
		
		Expand-Archive -Path $RemoteZipPath -DestinationPath $RemoteDeployPath -Force
		Write-Host "ZIP extracted to $RemoteDeployPath"
		
		# Optionally, delete the ZIP after extraction
		Remove-Item -Path $RemoteZipPath -Force -ErrorAction SilentlyContinue
		Write-Host "ZIP file deleted after extraction."
	}
	
	if ($Credential)
	{
		Invoke-Command -ComputerName $RemoteServer -Credential $Credential -ScriptBlock $ScriptBlock -ArgumentList $RemoteZipPath, $RemoteDeployPath
	}
	else
	{
		Invoke-Command -ComputerName $RemoteServer -ScriptBlock $ScriptBlock -ArgumentList $RemoteZipPath, $RemoteDeployPath
	}
	
	Write-Host "Deployment completed on $RemoteServer."
}


function Clear-RemoteDirectory
{
	param (
		[string]$RemoteServer = "KCI-APP01",
		# Remote machine name or IP

		[string]$TargetDirectory = "C:\inetpub\tracking\",
		# Directory to clear

		[string]$CredentialUser = "",
		# Optional username

		[securestring]$CredentialPassword # Optional password
	)
	
	# Create credentials if username and password are provided
	if ($CredentialUser -and $CredentialPassword)
	{
		$Credential = New-Object System.Management.Automation.PSCredential ($CredentialUser, $CredentialPassword)
	}
	else
	{
		$Credential = $null
	}
	
	# Define script block for remote execution
	$ScriptBlock = {
		param ($TargetDirectory)
		
		if (Test-Path $TargetDirectory)
		{
			Write-Host "Clearing all items from: $TargetDirectory"
			
			# Remove all files and subdirectories
			Get-ChildItem -Path $TargetDirectory -Recurse -Force | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
			
			# Confirm cleanup
			if (-Not (Get-ChildItem -Path $TargetDirectory -Force))
			{
				Write-Host "Cleanup successful: $TargetDirectory is now empty."
			}
			else
			{
				Write-Host "Warning: Some files may not have been removed."
			}
		}
		else
		{
			Write-Host "Error: Directory $TargetDirectory does not exist."
		}
	}
	
	# Execute on remote server
	if ($Credential)
	{
		Invoke-Command -ComputerName $RemoteServer -Credential $Credential -ScriptBlock $ScriptBlock -ArgumentList $TargetDirectory
	}
	else
	{
		Invoke-Command -ComputerName $RemoteServer -ScriptBlock $ScriptBlock -ArgumentList $TargetDirectory
	}
}


function Stop-IISAppRemote
{
	param (
		[string]$RemoteServer = "KCI-APP01",
		# Remote machine name or IP

		[string]$AppPoolName = "Tracking",
		[string]$SiteName = "Tracking",
		[string]$CredentialUser = "",
		[securestring]$CredentialPassword
	)
	
	# Create credentials if username and password are provided
	if ($CredentialUser -and $CredentialPassword)
	{
		$Credential = New-Object System.Management.Automation.PSCredential ($CredentialUser, $CredentialPassword)
	}
	else
	{
		$Credential = $null
	}
	
	# Run IIS stop commands on the remote machine
	$ScriptBlock = {
		param ($AppPoolName,
			$SiteName)
		
		Import-Module WebAdministration -ErrorAction Stop
		
		Write-Host "Stopping IIS Application Pool: $AppPoolName"
		if ((Get-WebAppPoolState -Name $AppPoolName).Value -ne "Stopped")
		{
			Stop-WebAppPool -Name $AppPoolName
			Write-Host "Application Pool '$AppPoolName' stopped successfully."
		}
		else
		{
			Write-Host "Application Pool '$AppPoolName' is already stopped."
		}
		
		Write-Host "Stopping IIS Site: $SiteName"
		if ((Get-WebSiteState -Name $SiteName).Value -ne "Stopped")
		{
			Stop-WebSite -Name $SiteName
			Write-Host "IIS Site '$SiteName' stopped successfully."
		}
		else
		{
			Write-Host "IIS Site '$SiteName' is already stopped."
		}
	}
	
	# Execute on remote server
	if ($Credential)
	{
		Invoke-Command -ComputerName $RemoteServer -Credential $Credential -ScriptBlock $ScriptBlock -ArgumentList $AppPoolName, $SiteName
	}
	else
	{
		Invoke-Command -ComputerName $RemoteServer -ScriptBlock $ScriptBlock -ArgumentList $AppPoolName, $SiteName
	}
}


function Cleanup
{
	param (
		[string]$DeployRoot = "F:\Development\CICD_TESTS\Tracking\",
		[string]$RemoteFile = "\\KCI-SYN-CL01\PC Transfer\zzip.zip",
		[string]$RepoDir = "test",
		[string]$ZipFileName = "zzip.zip"
	)
	
	$RepoPath = Join-Path -Path $DeployRoot -ChildPath $RepoDir
	$ZipFilePath = Join-Path -Path $DeployRoot -ChildPath $ZipFileName
	
	Write-Host "Starting cleanup..."
	
	# Kill any processes using the folder
	Write-Host "Checking for processes using the folder..."
	Get-Process | Where-Object { $_.Path -like "$RepoPath\*" } | Stop-Process -Force -ErrorAction SilentlyContinue
	
	# Use Remove-Item with error handling
	if (Test-Path $RepoPath)
	{
		Write-Host "Removing directory: $RepoPath"
		Try
		{
			Remove-Item -Path $RepoPath -Recurse -Force -Confirm:$false -ErrorAction Stop
			Remove-Item -Path $RemoteFile -Recurse -Force -Confirm:$false -ErrorAction Stop
			Write-Host "Successfully deleted: $RepoPath"
		}
		Catch
		{
			Write-Host "Warning: Unable to delete using Remove-Item. Trying RD command..."
			Start-Process -NoNewWindow -Wait -FilePath "cmd.exe" -ArgumentList "/c RD /S /Q `"$RepoPath`"" -ErrorAction SilentlyContinue
		}
	}
	
	# Delete the ZIP file
	if (Test-Path $ZipFilePath)
	{
		Write-Host "Deleting file: $ZipFilePath"
		Try
		{
			Remove-Item -Path $ZipFilePath -Force -Confirm:$false -ErrorAction Stop
			Write-Host "Successfully deleted: $ZipFilePath"
		}
		Catch
		{
			Write-Host "Warning: Unable to delete ZIP file. It may be in use."
		}
	}
	
	Write-Host "Force cleanup complete."
}


function Zip-Repo
{
	param (
		[string]$DeployRoot = "F:\Development\CICD_TESTS\Tracking\",
		[string]$RepoDir = "test",
		[string]$ZipFileName = "zzip.zip",
		[string]$TransferFolder = "\\KCI-SYN-CL01\PC Transfer\"
	)
	
	$RepoPath = Join-Path -Path $DeployRoot -ChildPath $RepoDir
	$ZipFilePath = Join-Path -Path $DeployRoot -ChildPath $ZipFileName
	$TransferZipPath = Join-Path -Path $TransferFolder -ChildPath $ZipFileName
	
	# Ensure the repository exists
	if (-Not (Test-Path $RepoPath))
	{
		Write-Host "Error: Repository folder not found at $RepoPath"
		return
	}
	
	Write-Host "Zipping repository contents..."
	Compress-Archive -Path "$RepoPath\*" -DestinationPath $ZipFilePath -Force
	
	Write-Host "Copying ZIP to transfer folder..."
	if (-Not (Test-Path $TransferFolder))
	{
		New-Item -ItemType Directory -Path $TransferFolder -Force
	}
	
	Copy-Item -Path $ZipFilePath -Destination $TransferZipPath -Force
	
	Write-Host "Zipping complete! ZIP saved to: $TransferZipPath"
}


# Define the Clone-Repo function
function Clone-Repo
{
	param (
		[string]$DeployRoot = "F:\Development\CICD_TESTS\Tracking\",
		[string]$RepoURL = "https://dcovington:_3ggUSA6YELP@onefortheroadgit.sytes.net/dcovington/tracking_kits",
		[string]$RepoDir = "test"
	)
	
	$RepoPath = Join-Path -Path $DeployRoot -ChildPath $RepoDir
	$SparseCheckoutFile = "$RepoPath\.git\info\sparse-checkout"
	$ConfigFilePath = "$RepoPath\App\app.config.asp"
	$ImportServicePath = "$RepoPath\ImportService\TrackingDataImport.vbs"
	Write-Host "Initializing Git repository..."
	Start-Process -NoNewWindow -Wait -FilePath "git" -ArgumentList "init $RepoPath"
	
	Start-Sleep -Seconds 2.5
	
	Write-Host "Setting current directory to $RepoPath"
	Set-Location -Path $RepoPath
	
	Write-Host "Adding remote repository..."
	Start-Process -NoNewWindow -Wait -FilePath "git" -ArgumentList "remote add -f origin $RepoURL"
	
	Write-Host "Enabling sparse checkout..."
	Start-Process -NoNewWindow -Wait -FilePath "git" -ArgumentList "config core.sparseCheckout true"
	
	Write-Host "Writing sparse checkout paths..."
	$SparseCheckoutPaths = @(
		"App/",
		"Data/arrow ne.jpg",
		"Data/Label_Report.rep",
		"Data/Delivery_Labels.rep",
		"Data/Delivery_PackingSlip.rep",
		"Data/png-transparent-arrow-arrow-angle-triangle-black-thumbnail.jpg",
		"Data/purple_envelope_sample_Page_1.jpg",
		"Data/purple_envelope_sample_Page_2.jpg",
		"Data/Custom Office Copies Proof.rep",
		"Data/Proofs.rep",
		"dist/",
		"MVC/",
		"Dependancies/",
		"ImportService/",
		"index.asp"
		# "web.config"
	)
	
	# Ensure the directory exists
	if (-Not (Test-Path "$RepoPath\.git\info"))
	{
		New-Item -ItemType Directory -Path "$RepoPath\.git\info" -Force
	}
	
	# Write sparse checkout paths
	$SparseCheckoutPaths | Set-Content -Path $SparseCheckoutFile -Force
	
	Write-Host "Pulling latest changes from master..."
	Start-Process -NoNewWindow -Wait -FilePath "git" -ArgumentList "pull origin master"
	
	# Wait for file existence
	Write-Host "Waiting for app.config.asp to be available..."
	while (-Not (Test-Path $ConfigFilePath))
	{
		Start-Sleep -Milliseconds 250
	}
	
	Write-Host "Updating app.config.asp..."
	$configContent = Get-Content -Path $ConfigFilePath -Raw
	$updatedConfigContent = $configContent -replace "dev = true", "dev = false"
	$updatedConfigContent | Set-Content -Path $ConfigFilePath -Force
	
	Write-Host "Updating ImportService.vbs..."
	$ImportServiceScript = Get-Content -Path $ImportServicePath -Raw
	$updatedImportServiceScript = $ImportServiceScript -replace 'Dim dev:dev = "local"', 'Dim dev:dev = false'
	$updatedImportServiceScript | Set-Content -Path $ImportServicePath -Force
	
	Write-Host "Repository cloned and configured successfully."
}

# Run the function
Clone-Repo
Zip-Repo
Stop-IISAppRemote
Clear-RemoteDirectory
Deploy-ZipRemote
Start-IISAppRemote
Cleanup
