#!/usr/bin/env bun
/**
 * Thai Font Patcher for picture-it
 * 
 * Detects if Thai font entries are missing from picture-it's FONT_FILES array
 * in dist/index.js, and patches them if needed.
 * 
 * This is idempotent — safe to run multiple times.
 * Run this after every `picture-it` update.
 * 
 * Usage:
 *   bun thai-font-patch.ts          # patch if needed
 *   bun thai-font-patch.ts --check  # just check, don't patch
 *   bun thai-font-patch.ts --force  # re-patch even if already patched
 */

import { readFileSync, writeFileSync, existsSync, cpSync, mkdirSync } from "fs";
import { join, dirname } from "path";
import { execSync } from "child_process";

const THAI_FONT_FILES_SIGNATURE = "thai/NotoSansThai-Regular.ttf";

const THAI_FONTS_ENTRY = `  },
  // Thai fonts
  {
    name: "Noto Sans Thai",
    file: "thai/NotoSansThai-Regular.ttf",
    weight: 400,
    style: "normal",
    url: "https://fonts.gstatic.com/s/notosansthai/v29/iJWnBXeUZi_OHPqn4wq6hQ2_hbJ1xyN9wd43SofNWcd1MKVQt_So_9CdU5RtpzE.ttf"
  },
  {
    name: "Noto Sans Thai",
    file: "thai/NotoSansThai-Bold.ttf",
    weight: 700,
    style: "normal",
    url: "https://fonts.gstatic.com/s/notosansthai/v29/iJWnBXeUZi_OHPqn4wq6hQ2_hbJ1xyN9wd43SofNWcd1MKVQt_So_9CdU3NqpzE.ttf"
  },
  {
    name: "Kanit",
    file: "thai/Kanit-Regular.ttf",
    weight: 400,
    style: "normal",
    url: "https://fonts.gstatic.com/s/kanit/v17/nKKZ-Go6G5tXcoaS.ttf"
  },
  {
    name: "Kanit",
    file: "thai/Kanit-Bold.ttf",
    weight: 700,
    style: "normal",
    url: "https://fonts.gstatic.com/s/kanit/v17/nKKU-Go6G5tXcr4uPiWg.ttf"
  }
];`

// Thai font download URLs
const THAI_FONTS_TO_DOWNLOAD = [
  {
    name: "NotoSansThai-Regular.ttf",
    url: "https://fonts.gstatic.com/s/notosansthai/v29/iJWnBXeUZi_OHPqn4wq6hQ2_hbJ1xyN9wd43SofNWcd1MKVQt_So_9CdU5RtpzE.ttf",
  },
  {
    name: "NotoSansThai-Bold.ttf",
    url: "https://fonts.gstatic.com/s/notosansthai/v29/iJWnBXeUZi_OHPqn4wq6hQ2_hbJ1xyN9wd43SofNWcd1MKVQt_So_9CdU3NqpzE.ttf",
  },
  {
    name: "Kanit-Regular.ttf",
    url: "https://fonts.gstatic.com/s/kanit/v17/nKKZ-Go6G5tXcoaS.ttf",
  },
  {
    name: "Kanit-Bold.ttf",
    url: "https://fonts.gstatic.com/s/kanit/v17/nKKU-Go6G5tXcr4uPiWg.ttf",
  },
];

function findPictureItDist(): string | null {
  const home = process.env.HOME || "";
  const searchPaths = [
    // bun-js snap (primary)
    join(home, "snap/bun-js/87/.bun/install/global/node_modules/picture-it/dist/index.js"),
    // npm global
    join(home, ".npm-global/lib/node_modules/picture-it/dist/index.js"),
  ];

  for (const p of searchPaths) {
    if (existsSync(p)) return p;
  }
  return null;
}

function getPictureItVersion(installDir: string): string {
  try {
    const pkgPath = join(installDir, "package.json");
    const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
    return pkg.version || "unknown";
  } catch {
    return "unknown";
  }
}

function getInstallDir(distPath: string): string {
  return dirname(dirname(distPath));
}

function isAlreadyPatched(distPath: string): boolean {
  const content = readFileSync(distPath, "utf-8");
  return content.includes(THAI_FONT_FILES_SIGNATURE);
}

async function downloadThaiFonts(fontDir: string): Promise<string[]> {
  mkdirSync(fontDir, { recursive: true });
  const downloaded: string[] = [];
  for (const font of THAI_FONTS_TO_DOWNLOAD) {
    const outPath = join(fontDir, font.name);
    if (existsSync(outPath)) {
      const stat = readFileSync(outPath);
      if (stat.length > 1000) {
        console.log(`  Already exists: ${font.name}`);
        downloaded.push(font.name);
        continue;
      }
    }
    console.log(`  Downloading: ${font.name}`);
    const res = await fetch(font.url);
    if (!res.ok) throw new Error(`Failed to download ${font.name}: ${res.status}`);
    const buf = await res.arrayBuffer();
    writeFileSync(outPath, Buffer.from(buf));
    downloaded.push(font.name);
  }
  return downloaded;
}

function patchDist(distPath: string): boolean {
  const content = readFileSync(distPath, "utf-8");
  
  // Find DM Serif Display closing brace in FONT_FILES array
  // Pattern: the last entry in FONT_FILES ends with:
  //     url: "https://fonts.gstatic.com/s/dmserifdisplay/v17/..."
  //   }
  // ];
  // We need to replace the closing `}` with Thai fonts entries + ];
  
  const dmSerifEntryEnd = `name: "DM Serif Display",
    file: "DMSerifDisplay-Regular.ttf",
    weight: 400,
    style: "normal",
    url: "https://fonts.gstatic.com/s/dmserifdisplay/v17/-nFnOHM81r4j6k0gjAW3mujVU2B2K_c.ttf"
  }`;

  // Find the closing of the array after DM Serif Display
  // We look for the pattern: DM Serif Display entry ... }; var cachedFonts
  // The `];` after the closing `}` of DM Serif Display is the end of FONT_FILES
  const fontFilesEndPattern = /(\n\s+url: "https:\/\/fonts\.gstatic\.com\/s\/dmserifdisplay\/v17\/[^"]+"\n\s+}\n)\];/;
  
  const match = content.match(fontFilesEndPattern);
  if (!match) {
    // Try alternate pattern (might differ in minified versions)
    const altPattern = /(\}\n)\];/;
    const altMatch = content.match(altPattern);
    if (!altMatch) {
      throw new Error("Could not find end of FONT_FILES array. picture-it format may have changed.");
    }
    // Just replace the first occurrence of ]; after a }
    const newContent = content.replace(altPattern, THAI_FONTS_ENTRY.replace("  },", match?.[1] || "  }").endsWith("}") ? THAI_FONTS_ENTRY : `  },${THAI_FONTS_ENTRY.split("  },")[1]}`);
    writeFileSync(distPath, newContent);
    return true;
  }

  const patched = content.replace(
    fontFilesEndPattern,
    THAI_FONTS_ENTRY
  );

  if (patched === content) {
    return false;
  }

  writeFileSync(distPath, patched);
  return true;
}

async function main() {
  const args = process.argv.slice(2);
  const checkOnly = args.includes("--check");
  const force = args.includes("--force");

  console.log("[Thai Font Patcher for picture-it]");
  console.log("");

  const distPath = findPictureItDist();
  
  if (!distPath) {
    console.log("ERROR: picture-it not found.");
    console.log("Is picture-it installed? Run: bun install -g picture-it");
    process.exit(1);
  }

  const installDir = getInstallDir(distPath);
  const version = getPictureItVersion(installDir);
  
  console.log(`picture-it found:  v${version}`);
  console.log(`Install dir:      ${installDir}`);
  console.log(`dist path:        ${distPath}`);
  console.log("");

  const alreadyPatched = isAlreadyPatched(distPath);
  
  if (alreadyPatched && !force) {
    console.log("Thai fonts: ALREADY PATCHED ✓");
    console.log("No action needed.");
    process.exit(0);
  }

  if (checkOnly) {
    console.log("Thai fonts: NOT PATCHED ✗");
    console.log("Run without --check to apply patch.");
    process.exit(1);
  }

  if (force && alreadyPatched) {
    console.log("Force mode: re-patching...");
  }

  // Step 1: Download Thai fonts
  console.log("Step 1: Ensuring Thai fonts are downloaded...");
  const fontDir = join(process.env.HOME || "", ".picture-it/fonts/thai");
  try {
    await downloadThaiFonts(fontDir);
  } catch (e: any) {
    console.error(`  Failed to download fonts: ${e.message}`);
    console.error("You can download them manually or try again.");
  }
  console.log("");

  // Step 2: Patch dist/index.js
  console.log("Step 2: Patching dist/index.js...");
  try {
    const success = patchDist(distPath);
    if (success) {
      console.log("  Patched dist/index.js ✓");
    } else {
      console.log("  No changes needed (or patch failed silently)");
    }
  } catch (e: any) {
    console.error(`  Patch failed: ${e.message}`);
    console.error("Please report this issue.");
    process.exit(1);
  }
  console.log("");

  // Verify
  const verifyPatched = isAlreadyPatched(distPath);
  if (verifyPatched) {
    console.log("RESULT: Thai font patch applied successfully ✓");
    console.log("");
    console.log("You can now use Thai fonts:");
    console.log('  picture-it text -i input.png --title "ทดสอบ" --font "Noto Sans Thai" -o out.png');
    console.log('  picture-it text -i input.png --title "ทดสอบ" --font "Kanit" -o out.png');
  } else {
    console.error("RESULT: Patch verification failed ✗");
    console.error("The patch may not have been applied correctly.");
    process.exit(1);
  }
}

main().catch((e: Error) => {
  console.error(`Error: ${e.message}`);
  process.exit(1);
});
