#!/usr/bin/env node

/**
 * Git post-checkout hook for auto-configuring worktree environments.
 * This runs after 'git checkout' or 'git worktree add'.
 *
 * Args from git:
 *   process.argv[2] - previous HEAD ref
 *   process.argv[3] - new HEAD ref
 *   process.argv[4] - flag (1 = branch checkout, 0 = file checkout)
 */

import fs from 'fs';
import path from 'path';
import { execSync, execFileSync } from 'child_process';
import { fileURLToPath } from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

const isBranchCheckout = process.argv[4] === '1';

if (!isBranchCheckout) {
  process.exit(0);
}

// Check if we're in a worktree by looking for .git file (not directory)
const gitPath = path.join(process.cwd(), '.git');
const isWorktree = fs.existsSync(gitPath) && fs.statSync(gitPath).isFile();

if (!isWorktree) {
  process.exit(0);
}

const envLocalPath = path.join(process.cwd(), '.env.local');

// Don't overwrite existing .env.local
if (fs.existsSync(envLocalPath)) {
  process.exit(0);
}

console.log('Detected new worktree - configuring ports in .env.local');

// Find the highest ports in use across all worktrees
// Main worktree (first in list) is assumed to use default ports 1420/64343
let maxMcpPort = 64343;
let maxDevPort = 1420;

try {
  const worktreeList = execSync('git worktree list --porcelain', { encoding: 'utf8' });
  const worktreePaths = worktreeList
    .split('\n')
    .filter(line => line.startsWith('worktree '))
    .map(line => line.replace('worktree ', '').trim());

  // Skip the first worktree (main) since it uses default ports
  for (let i = 1; i < worktreePaths.length; i++) {
    const worktreePath = worktreePaths[i];
    const envPath = path.join(worktreePath, '.env.local');

    if (fs.existsSync(envPath)) {
      const content = fs.readFileSync(envPath, 'utf8');

      const mcpMatch = content.match(/^YAAK_PLUGIN_MCP_SERVER_PORT=(\d+)/m);
      if (mcpMatch) {
        const port = parseInt(mcpMatch[1], 10);
        if (port > maxMcpPort) {
          maxMcpPort = port;
        }
      }

      const devMatch = content.match(/^YAAK_DEV_PORT=(\d+)/m);
      if (devMatch) {
        const port = parseInt(devMatch[1], 10);
        if (port > maxDevPort) {
          maxDevPort = port;
        }
      }
    }
  }

  // Increment to get the next available port
  maxDevPort++;
  maxMcpPort++;
} catch (err) {
  console.error('Warning: Could not check other worktrees for port conflicts:', err.message);
  // Continue with default ports
}

// Get worktree name from current directory
const worktreeName = path.basename(process.cwd());

// Create .env.local with unique ports
const envContent = `# Auto-generated by git post-checkout hook
# This file configures ports for this worktree to avoid conflicts

# Vite dev server port (main worktree uses 1420)
YAAK_DEV_PORT=${maxDevPort}

# MCP Server port (main worktree uses 64343)
YAAK_PLUGIN_MCP_SERVER_PORT=${maxMcpPort}
`;

fs.writeFileSync(envLocalPath, envContent, 'utf8');
console.log(`Created .env.local with YAAK_DEV_PORT=${maxDevPort} and YAAK_PLUGIN_MCP_SERVER_PORT=${maxMcpPort}`);

// Create tauri.worktree.conf.json with unique app identifier for complete isolation
// This gives each worktree its own app data directory, avoiding the need for DB path prefixes
const tauriWorktreeConfig = {
  identifier: `app.yaak.desktop.dev.${worktreeName}`,
  productName: `Daak (${worktreeName})`
};

const tauriConfigPath = path.join(process.cwd(), 'crates-tauri', 'yaak-app', 'tauri.worktree.conf.json');
fs.writeFileSync(tauriConfigPath, JSON.stringify(tauriWorktreeConfig, null, 2) + '\n', 'utf8');
console.log(`Created tauri.worktree.conf.json with identifier: ${tauriWorktreeConfig.identifier}`);

// Copy gitignored editor config folders from main worktree (.zed, .vscode, .claude, etc.)
// This ensures your editor settings, tasks, and configurations are available in the new worktree
// without needing to manually copy them or commit them to git.
try {
  const worktreeList = execSync('git worktree list --porcelain', { encoding: 'utf8' });
  const mainWorktreePath = worktreeList
    .split('\n')
    .find(line => line.startsWith('worktree '))
    ?.replace('worktree ', '')
    .trim();

  if (mainWorktreePath) {
    // Find all .* folders in main worktree root that are gitignored
    const entries = fs.readdirSync(mainWorktreePath, { withFileTypes: true });
    const dotFolders = entries
      .filter(entry => entry.isDirectory() && entry.name.startsWith('.'))
      .map(entry => entry.name);

    for (const folder of dotFolders) {
      const sourcePath = path.join(mainWorktreePath, folder);
      const destPath = path.join(process.cwd(), folder);

      try {
        // Check if it's gitignored - run from main worktree directory
        execFileSync('git', ['check-ignore', '-q', folder], {
          stdio: 'pipe',
          cwd: mainWorktreePath
        });

        // It's gitignored, copy it
        fs.cpSync(sourcePath, destPath, { recursive: true });
        console.log(`Copied ${folder} from main worktree`);
      } catch {
        // Not gitignored or doesn't exist, skip
      }
    }
  }
} catch (err) {
  console.warn('Warning: Could not copy files from main worktree:', err.message);
  // Continue anyway
}

console.log('\n✓ Worktree setup complete! Run `npm run init` to install dependencies.');
