Param (
        [Parameter(Mandatory=$true)][String]$EXEID,
        [Parameter(Mandatory=$true)][ValidateSet('Original','ReDMCSB','Build')][String]$Instance,
        [switch]$Force
)

$IDAPath = "D:\Software\Local\IDA Pro\ida61\idag.exe"


$ReDMCSBPath = (Get-Item $PSScriptRoot).Parent.Parent.Parent.FullName
$Executables = Import-CSV -Delimiter "`t" -Path "$PSScriptRoot\Executables.txt"
$Executable = $Executables | Where-Object { $_.ID -eq $EXEID }
$Media = $Executable.Media
$ExecutableFormat = $Executable.Format
$ExecutableFile = $Executable.Name
$ExecutableFolder = "$ReDMCSBPath\Reference\Original\$Media"
switch ($Instance) {
        'ReDMCSB' {
                $ReferenceReDMCSBExecutableFolder = "$ReDMCSBPath\Reference\ReDMCSB\$Media"
                if (Test-Path -Path "$ReferenceReDMCSBExecutableFolder\$ExecutableFile" -PathType Leaf) {
                        $ExecutableFolder = $ReferenceReDMCSBExecutableFolder
                }
        }
        'Build' {
                $ExecutableFolder = "$ReDMCSBPath\Output\$($Executable.Toolchain)\HARDDISK\BUILD\$Media"
        }
}

$ExecutablePath = "$ExecutableFolder\$ExecutableFile"
$Identifier = "$($Media)_$($ExecutableFile)_$Instance"
$OutputAnalysisPath = "$ReDMCSBPath\Output\Analysis"
$OutputBINFolderPath = "$OutputAnalysisPath\BIN\$Identifier"
$OutputBINDatabasePath = "$OutputAnalysisPath\BIN\$Identifier.idb"
$OutputTXTPath = "$OutputAnalysisPath\TXT\$Identifier.txt"
$OutputHashPath = "$OutputAnalysisPath\Hash\$Identifier.txt"
$null = New-Item -Path "$OutputAnalysisPath"      -ItemType Directory -Force
$null = New-Item -Path "$OutputAnalysisPath\TXT"  -ItemType Directory -Force
$null = New-Item -Path "$OutputAnalysisPath\BIN"  -ItemType Directory -Force
$null = New-Item -Path "$OutputAnalysisPath\Hash" -ItemType Directory -Force

$ExecutableHash = "NoExecutableHash"
$OutputHash = "NoPreviousHash"
if (-not (Test-Path -Path $ExecutablePath -PathType Leaf)) {
        Write-Host "File not found   [$ExecutablePath]: " -ForegroundColor Red -BackgroundColor Black
        exit
} else {
        if ((Get-Item -Path $ExecutablePath).Length -eq 0) {
                Write-Host "File is empty    [$ExecutablePath]" -ForegroundColor Red -BackgroundColor Black
                exit
        } else {
                if (Test-Path -Path $OutputHashPath -PathType Leaf) {
                        $OutputHash = Get-Content -Path $OutputHashPath
                }
                $ExecutableHash = (Get-FileHash -Path $ExecutablePath -Algorithm SHA1).Hash
                if (($ExecutableHash -ne $OutputHash) -or $Force) {
                        Write-Host "Analysis of      [$ExecutablePath] to"
                        Write-Host "                 [$OutputTXTPath]"
                } else {
                        Write-Host "Already analysed [$ExecutablePath] to" -ForegroundColor Yellow -BackgroundColor Black
                        Write-Host "                 [$OutputTXTPath]" -ForegroundColor Yellow -BackgroundColor Black
                        exit
                }
        }
}

function RunCommandLine {
Param (
        [String]$FilePath,
        [String]$ArgumentList,
        [String]$WorkingDirectory
)
        
        # Write-Host $ArgumentList
        if (Test-Path -Path $FilePath -PathType Leaf) {
                Start-Process -Wait -WindowStyle Minimized -FilePath $FilePath -ArgumentList $ArgumentList -WorkingDirectory $WorkingDirectory
        } else {
                Write-Host "File not found: $FilePath" -ForegroundColor Yellow -BackgroundColor Black
        }
}

Set-Content -Path $OutputHashPath -Value $ExecutableHash
switch ($ExecutableFormat) {
        'Binary68000' {
                Write-Host "No analysis available for this executable format" -ForegroundColor Yellow -BackgroundColor Black
        }
        'Binary65C816' {
                Write-Host "No analysis available for this executable format" -ForegroundColor Yellow -BackgroundColor Black
        }
        'X' {
                Write-Host "No analysis available for this executable format" -ForegroundColor Yellow -BackgroundColor Black
        }
        'Hunk' {
                RunCommandLine -FilePath $IDAPath -ArgumentList "-o`"$OutputBINDatabasePath`" -TAmiga -A -S`"\`"$PSScriptRoot\Hunk_EXE_EXP.idc\`" \`"$OutputTXTPath\`"`" `"$ExecutablePath`"" -WorkingDirectory $OutputAnalysisPath
        }
        'EXE' {
                $Bytes = Get-Content -Path $ExecutablePath -Encoding Byte -TotalCount 32
                if (($Bytes[28] -eq 0x4C) -and ($Bytes[29] -eq 0x5A) -and ($Bytes[30] -eq 0x39) -and ($Bytes[31] -eq 0x31)) { # Detect 'LZ91' compressed executable
                        $null = New-Item -Path "$ReDMCSBPath\Output\Expanded" -ItemType Directory -Force
                        $null = New-Item -Path "$ReDMCSBPath\Output\Expanded\$Instance" -ItemType Directory -Force
                        $null = New-Item -Path "$ReDMCSBPath\Output\Expanded\$Instance\$Media" -ItemType Directory -Force
                        $ExpandedExecutablePath = "$ReDMCSBPath\Output\Expanded\$Instance\$Media\$ExecutableFile"
                        RunCommandLine -FilePath "$PSScriptRoot\UNLZEXE\unlzexe.exe" -ArgumentList "`"$ExecutablePath`" `"$ExpandedExecutablePath`"" -WorkingDirectory $OutputAnalysisPath
                        $ExecutablePath = $ExpandedExecutablePath
                }
                RunCommandLine -FilePath $IDAPath -ArgumentList "-o`"$OutputBINDatabasePath`" -TMS    -A -S`"\`"$PSScriptRoot\Hunk_EXE_EXP.idc\`" \`"$OutputTXTPath\`"`" `"$ExecutablePath`"" -WorkingDirectory $OutputAnalysisPath
        }
        'EXP' {
                RunCommandLine -FilePath $IDAPath -ArgumentList "-o`"$OutputBINDatabasePath`" -TPhar  -A -S`"\`"$PSScriptRoot\Hunk_EXE_EXP.idc\`" \`"$OutputTXTPath\`"`" `"$ExecutablePath`"" -WorkingDirectory $OutputAnalysisPath
        }
        'PRG' {
                $Bytes = Get-Content -Path $ExecutablePath -Encoding Byte -TotalCount 6
                if (($Bytes[4] -eq 0x60) -and ($Bytes[5] -eq 0x1A)) {
                        $null = New-Item -Path "$ReDMCSBPath\Output\Expanded" -ItemType Directory -Force
                        $null = New-Item -Path "$ReDMCSBPath\Output\Expanded\$Instance" -ItemType Directory -Force
                        $null = New-Item -Path "$ReDMCSBPath\Output\Expanded\$Instance\$Media" -ItemType Directory -Force
                        $ExpandedExecutablePath = "$ReDMCSBPath\Output\Expanded\$Instance\$Media\$ExecutableFile"
                        & "$PSScriptRoot\Expand-AtariSTPAK.ps1" -SourcePath $ExecutablePath -DestinationPath $ExpandedExecutablePath
                        $ExecutablePath = $ExpandedExecutablePath
                }
                RunCommandLine -FilePath $IDAPath -ArgumentList "-o`"$OutputBINDatabasePath`" -t -p68000 -A -S`"\`"$PSScriptRoot\PRG.idc\`" \`"$OutputTXTPath\`" \`"$ExecutablePath\`"`"" -WorkingDirectory $OutputAnalysisPath
        }
        'FTL' {
                # Cleanup output BIN folder to restart from scratch
                if (Test-Path -Path $OutputBINFolderPath -PathType Container) {
                        & "$PSScriptRoot\Remove-Folder.ps1" -Path $OutputBINFolderPath -TemporaryPath "$ReDMCSBPath\Output"
                        if (Test-Path -Path $OutputBINFolderPath -PathType Container) {
                                Write-Host "Failed to delete folder [$OutputBINFolderPath]. Make sure you don't have any file or program open in that location." -ForegroundColor Red -BackgroundColor Black
                                Read-Host -Prompt "Press enter to exit"
                                exit
                        }
                }
                $null = New-Item -Path $OutputBINFolderPath -ItemType Directory -Force
                & "$PSScriptRoot\ConvertFrom-FTL.ps1" -FTLFileName $ExecutablePath -OutputBaseFileName "$OutputBINFolderPath\$Identifier"
                RunCommandLine -FilePath $IDAPath -ArgumentList "-o`"$OutputBINDatabasePath`" -t -p68000 -A -S`"\`"$PSScriptRoot\FTL.idc\`" \`"$OutputTXTPath\`" \`"$($OutputBINFolderPath)\$($Identifier)_\`" \`"$EXEID\`"`"" -WorkingDirectory $OutputAnalysisPath
        }
        'OMF' {
                # Cleanup output BIN folder to restart from scratch
                if (Test-Path -Path $OutputBINFolderPath -PathType Container) {
                        & "$PSScriptRoot\Remove-Folder.ps1" -Path $OutputBINFolderPath -TemporaryPath "$ReDMCSBPath\Output"
                        if (Test-Path -Path $OutputBINFolderPath -PathType Container) {
                                Write-Host "Failed to delete folder [$OutputBINFolderPath]. Make sure you don't have any file or program open in that location." -ForegroundColor Red -BackgroundColor Black
                                Read-Host -Prompt "Press enter to exit"
                                exit
                        }
                }
                $null = New-Item -Path $OutputBINFolderPath -ItemType Directory -Force
                RunCommandLine -FilePath "$Env:ComSpec" -ArgumentList "/c java.exe dumpobj -d `"$ExecutablePath`" > `"$OutputTXTPath`"" -WorkingDirectory "$PSScriptRoot\OMFUtils"
                & "$PSScriptRoot\ConvertFrom-AppleIIGSOMF.ps1" -SourcePath $ExecutablePath -DestinationPath $OutputBINFolderPath
        }
}
