#!/usr/bin/env node

const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const os = require('os');

// Map node os.platform() to release asset naming convention
const platformMap = {
  darwin: 'darwin',
  linux: 'linux',
  win32: 'windows'
};

const archMap = {
  x64: 'amd64',
  arm64: 'arm64',
  ia32: '386'
};

const platform = platformMap[os.platform()];
const arch = archMap[os.arch()];

if (!platform || !arch) {
  console.error(`Unsupported platform: ${os.platform()} ${os.arch()}`);
  process.exit(1);
}

const isWindows = platform === 'windows';
const ext = isWindows ? '.exe' : '';

// The correct binary for this platform from prebuilds
const correctBinaryName = `sk-${platform}-${arch}${ext}`;
const correctBinaryPath = path.join(__dirname, 'prebuilds', correctBinaryName);

// Where npm expects the bin to be
const npmBinPath = path.join(__dirname, 'bin', 'sk' + ext);

function installFromPrebuild() {
  // Check if correct binary exists in prebuilds
  if (fs.existsSync(correctBinaryPath)) {
    // Ensure bin directory exists
    const binDir = path.join(__dirname, 'bin');
    if (!fs.existsSync(binDir)) {
      fs.mkdirSync(binDir, { recursive: true });
    }

    // Copy the correct binary to bin/sk (or bin/sk.exe on Windows)
    fs.copyFileSync(correctBinaryPath, npmBinPath);

    // On Windows, also create sk without .exe extension for some tools
    if (isWindows) {
      const binPathNoExt = path.join(__dirname, 'bin', 'sk');
      if (!fs.existsSync(binPathNoExt)) {
        fs.copyFileSync(correctBinaryPath, binPathNoExt);
      }
    }

    // Make executable
    if (!isWindows) {
      fs.chmodSync(npmBinPath, 0o755);
    }

    console.log(`Installed ${correctBinaryName}`);
    return true;
  }
  return false;
}

// Main
const installed = installFromPrebuild();
if (!installed) {
  // This should not happen if package is built correctly
  console.error(`Prebuild not found for ${platform}-${arch}. Please reinstall @hiu_yan_chong/sk-cli.`);
  process.exit(1);
}

// On Windows, also create .cmd wrapper to ensure PowerShell/CMD can find it
if (isWindows) {
  const npmPrefix = execSync('npm config get prefix', { encoding: 'utf8' }).trim();
  
  // Create .cmd file that explicitly calls our .exe
  const cmdPath = path.join(npmPrefix, 'sk.cmd');
  const nodeModulesPath = path.join(npmPrefix, 'node_modules', '@hiu_yan_chong', 'sk-cli');
  const exePath = path.join(nodeModulesPath, 'bin', 'sk.exe');
  
  const cmdContent = `@echo off
"${exePath}" %*
`;
  
  try {
    fs.writeFileSync(cmdPath, cmdContent);
    console.log('Created sk.cmd wrapper');
  } catch (err) {
    console.log(`Note: Could not create sk.cmd: ${err.message}`);
  }
  
  // Also try to create sk.ps1 that points to .exe
  const ps1Path = path.join(npmPrefix, 'sk.ps1');
  const ps1Content = `# This is a workaround for PowerShell
& "${exePath}" $args
`;
  try {
    fs.writeFileSync(ps1Path, ps1Content);
    console.log('Created sk.ps1 wrapper');
  } catch (err) {
    // Ignore
  }
}

// Verify npm bin link works - check if it's a broken shell script (Git Bash on Windows)
const npmPrefix = execSync('npm config get prefix', { encoding: 'utf8' }).trim();

// On Windows, npm might create sk (no ext) or sk.cmd - check both
const possibleShims = isWindows
  ? [path.join(npmPrefix, 'sk'), path.join(npmPrefix, 'sk.cmd'), path.join(npmPrefix, 'sk.exe')]
  : [path.join(npmPrefix, 'sk')];

for (const npmShimPath of possibleShims) {
  if (!fs.existsSync(npmShimPath)) continue;

  // Read first 2 bytes to check for shebang (#!)
  const fd = fs.openSync(npmShimPath, 'r');
  const buffer = Buffer.alloc(2);
  fs.readSync(fd, buffer, 0, 2, 0);
  fs.closeSync(fd);

  // If starts with #! (0x23 0x21), it's a shell script - broken on Windows
  const isShebang = buffer[0] === 0x23 && buffer[1] === 0x21;

  if (isShebang) {
    console.log('Fixing npm bin link (detected shell shim)...');
    try {
      fs.unlinkSync(npmShimPath);
    } catch {}

    // Create direct copy of our binary
    const ourBinary = path.join(__dirname, 'bin', 'sk' + ext);
    try {
      // Copy binary to where npm expects it
      fs.copyFileSync(ourBinary, npmShimPath);
      console.log('Fixed npm bin link');
    } catch (err) {
      console.log(`Note: Could not fix npm bin link. Use: ${ourBinary}`);
    }
    break;
  }
}
