# Generates dependency notice snapshots for paid release artifacts.
param(
    [string]$Root = (Resolve-Path "$PSScriptRoot\..").Path
)

$ErrorActionPreference = "Stop"

$LicensesDir = Join-Path $Root "licenses"
New-Item -ItemType Directory -Force -Path $LicensesDir | Out-Null

if (-not (Test-Path (Join-Path $Root "package-lock.json"))) {
    throw "Missing package-lock.json. Run npm install first."
}

if (-not (Test-Path (Join-Path $Root "src-tauri\Cargo.toml"))) {
    throw "Missing src-tauri/Cargo.toml."
}

$NodeScript = @'
const fs = require("fs");
const path = require("path");
const cp = require("child_process");

const root = process.argv[2];
const licensesDir = path.join(root, "licenses");
fs.mkdirSync(licensesDir, { recursive: true });

function cell(value) {
  return String(value ?? "UNKNOWN").replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
}

function uniqueSorted(rows, keyFn) {
  const map = new Map();
  for (const row of rows) {
    map.set(keyFn(row), row);
  }
  return Array.from(map.values()).sort((a, b) => keyFn(a).localeCompare(keyFn(b)));
}

const packageLock = JSON.parse(fs.readFileSync(path.join(root, "package-lock.json"), "utf8"));
const npmRows = [];

for (const [packagePath, pkg] of Object.entries(packageLock.packages || {})) {
  if (!packagePath || !packagePath.includes("node_modules/")) continue;

  npmRows.push({
    name: packagePath.split("node_modules/").pop(),
    version: pkg.version || "UNKNOWN",
    license: pkg.license || "UNKNOWN",
    kind: pkg.dev ? "dev" : "prod",
  });
}

const npmLines = [
  "Slipstream DRC npm Dependency Notices",
  "",
  "Generated from package-lock.json. Third-party packages remain governed by their upstream licenses.",
  "",
  "| Package | Version | License | Scope |",
  "|---------|---------|---------|-------|",
];

for (const row of uniqueSorted(npmRows, (row) => `${row.name}@${row.version}:${row.kind}`)) {
  npmLines.push(`| ${cell(row.name)} | ${cell(row.version)} | ${cell(row.license)} | ${cell(row.kind)} |`);
}

fs.writeFileSync(path.join(licensesDir, "npm-dependencies.txt"), npmLines.join("\n") + "\n", "utf8");

const cargoJson = cp.execFileSync("cargo", ["metadata", "--format-version", "1", "--locked"], {
  cwd: path.join(root, "src-tauri"),
  encoding: "utf8",
  maxBuffer: 64 * 1024 * 1024,
});

const cargoMetadata = JSON.parse(cargoJson);
const rustRows = [];

for (const pkg of cargoMetadata.packages || []) {
  if (!pkg.source) continue;

  rustRows.push({
    name: pkg.name,
    version: pkg.version,
    license: pkg.license || (pkg.license_file ? "SEE LICENSE FILE" : "UNKNOWN"),
    source: pkg.source,
  });
}

const rustLines = [
  "Slipstream DRC Rust Dependency Notices",
  "",
  "Generated from cargo metadata --locked. Third-party crates remain governed by their upstream licenses.",
  "",
  "| Crate | Version | License | Source |",
  "|-------|---------|---------|--------|",
];

for (const row of uniqueSorted(rustRows, (row) => `${row.name}@${row.version}`)) {
  rustLines.push(`| ${cell(row.name)} | ${cell(row.version)} | ${cell(row.license)} | ${cell(row.source)} |`);
}

fs.writeFileSync(path.join(licensesDir, "rust-dependencies.txt"), rustLines.join("\n") + "\n", "utf8");

console.log("Generated dependency notices:");
console.log("  licenses/npm-dependencies.txt");
console.log("  licenses/rust-dependencies.txt");
'@

$NodeScript | node - $Root
if ($LASTEXITCODE -ne 0) {
    throw "Dependency notice generation failed."
}
