# SM-Emby Dev Run Helper

$Device = 'windows'
$Force = $false
$Offline = $false
$RefreshFvpDeps = $false
$SkipDefenderCheck = $false
$FlutterArgs = @()

for ($i = 0; $i -lt $args.Count; $i++) {
  $arg = [string]$args[$i]
  switch ($arg) {
    '-Device' {
      $i++
      if ($i -ge $args.Count) { throw 'Missing value for -Device' }
      $Device = [string]$args[$i]
      continue
    }
    '-Force' { $Force = $true; continue }
    '-Offline' { $Offline = $true; continue }
    '-RefreshFvpDeps' { $RefreshFvpDeps = $true; continue }
    '-SkipDefenderCheck' { $SkipDefenderCheck = $true; continue }
    '-FlutterArgs' {
      if ($i + 1 -lt $args.Count) { $FlutterArgs = @($args[($i + 1)..($args.Count - 1)]) }
      $i = $args.Count
      continue
    }
    '--' {
      if ($i + 1 -lt $args.Count) { $FlutterArgs = @($args[($i + 1)..($args.Count - 1)]) }
      $i = $args.Count
      continue
    }
    default { throw "Unknown argument: $arg" }
  }
}

$ErrorActionPreference = 'Stop'

$repoRoot = Split-Path -Parent $PSScriptRoot
Set-Location $repoRoot
. (Join-Path $PSScriptRoot 'version-common.ps1')

$pubspec       = Join-Path $repoRoot 'pubspec.yaml'
$pubspecLock   = Join-Path $repoRoot 'pubspec.lock'
$packageConfig = Join-Path $repoRoot '.dart_tool/package_config.json'
$pubGetStamp   = Join-Path $repoRoot '.dart_tool/.dev-run-pubget.stamp'

function Get-PubDepsFingerprint {
  $parts = @()
  foreach ($file in @($pubspec, $pubspecLock)) {
    if (Test-Path $file) {
      $parts += (Get-FileHash -Path $file -Algorithm SHA256).Hash
    } else {
      $parts += 'missing'
    }
  }
  return ($parts -join ':')
}

function Need-PubGet {
  if ($Force)                              { return $true }
  if (-not (Test-Path $packageConfig))     { return $true }
  if (-not (Test-Path $pubspec))           { return $true }
  if (-not (Test-Path $pubGetStamp))       { return $true }

  $previousFingerprint = (Get-Content -Path $pubGetStamp -Raw -ErrorAction SilentlyContinue).Trim()
  return ($previousFingerprint -ne (Get-PubDepsFingerprint))
}

function Save-PubGetStamp {
  Set-Content -Path $pubGetStamp -Value (Get-PubDepsFingerprint) -NoNewline -Encoding ASCII
}

function Disable-FvpLatestForDevRun {
  if ($Device.ToLowerInvariant() -ne 'windows') { return }
  if (-not $Env:FVP_DEPS_LATEST) { return }

  Write-Host '[dev-run] 清理 FVP_DEPS_LATEST，使用项目固定版本的 fvp/mdk-sdk' -ForegroundColor Green
  $Env:FVP_DEPS_LATEST = $null
}

function Prepare-PinnedFvpWindowsDependencies {
  if ($Device.ToLowerInvariant() -ne 'windows') { return }

  $prepareScript = Join-Path $PSScriptRoot 'prepare-fvp-windows-deps.ps1'
  $prepareArguments = @('-ExecutionPolicy', 'Bypass', '-File', $prepareScript)
  if ($RefreshFvpDeps) { $prepareArguments += '-ForceRefresh' }

  & powershell @prepareArguments
  if ($LASTEXITCODE -ne 0) {
    throw "Failed to prepare pinned fvp Windows dependencies (exit $LASTEXITCODE)"
  }
}

function Test-DefenderExclusion {
  if ($SkipDefenderCheck) { return }
  if ($Device.ToLowerInvariant() -ne 'windows') { return }

  try {
    $pref = Get-MpPreference -ErrorAction Stop
  } catch {
    return
  }

  $root = $repoRoot.TrimEnd('\').ToLowerInvariant()
  $covered = $false
  foreach ($ex in @($pref.ExclusionPath)) {
    if ([string]::IsNullOrWhiteSpace($ex)) { continue }
    $e = $ex.TrimEnd('\').ToLowerInvariant()
    if ($root -eq $e -or $root.StartsWith($e + '\')) { $covered = $true; break }
  }

  if ($covered) {
    Write-Host '[dev-run] Windows Defender 已排除项目目录，原生编译不受实时扫描拖慢' -ForegroundColor Green
    return
  }

  Write-Host '[dev-run] 提示: 项目目录未加入 Windows Defender 排除，原生(fvp/libmdk)编译可能被实时扫描显著拖慢' -ForegroundColor Yellow
  Write-Host '          用【管理员】PowerShell 执行一次即可（之后走缓存）:' -ForegroundColor Yellow
  Write-Host ('            Add-MpPreference -ExclusionPath "' + $repoRoot + '"') -ForegroundColor DarkYellow
  Write-Host '          加 -SkipDefenderCheck 可跳过本提示' -ForegroundColor DarkGray
}

$sw = [System.Diagnostics.Stopwatch]::StartNew()
Disable-FvpLatestForDevRun
Test-DefenderExclusion

if (Need-PubGet) {
  Write-Host '[dev-run] 依赖有变更 -> flutter pub get' -ForegroundColor Yellow
  $pubArgs = @('pub', 'get')
  if ($Offline) { $pubArgs += '--offline' }
  & flutter @pubArgs
  if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
  Save-PubGetStamp
} else {
  Write-Host '[dev-run] 依赖未变更 -> 跳过 pub get' -ForegroundColor Green
}

Prepare-PinnedFvpWindowsDependencies

$appVersion = Get-SmPlayerCurrentVersion -Platform windows -ProjectRoot $repoRoot
Write-Host "[dev-run] App version: $appVersion (windows/pc line)" -ForegroundColor Cyan

$runArgs = @('run', '-d', $Device, '--no-pub')
if ($FlutterArgs) { $runArgs += $FlutterArgs }
$runArgs = Add-SmPlayerVersionDartDefine -Arguments $runArgs -Version $appVersion

Write-Host "[dev-run] flutter $($runArgs -join ' ')" -ForegroundColor Cyan
Write-Host "[dev-run] 启动准备耗时: $([int]$sw.Elapsed.TotalMilliseconds) ms" -ForegroundColor DarkGray

& flutter @runArgs
exit $LASTEXITCODE
