import { SessionMonitor } from "../../core/monitoring/session-monitor";
import { FrameManager } from "../../core/frame/frame-manager";
import { DatabaseManager } from "../../core/storage/database-manager";
import * as fs from "fs/promises";
import * as path from "path";
import * as os from "os";
class ClaudeCodeLifecycleHooks {
  monitor;
  config;
  isActive = false;
  hookScripts = /* @__PURE__ */ new Map();
  constructor(config) {
    this.config = {
      ...config,
      claudeHooksPath: config.claudeHooksPath || path.join(os.homedir(), ".claude", "hooks")
    };
  }
  /**
   * Initialize hooks and start monitoring
   */
  async initialize() {
    if (this.isActive) return;
    const dbPath = path.join(
      this.config.projectRoot,
      ".stackmemory",
      "db",
      "stackmemory.db"
    );
    const dbManager = new DatabaseManager(dbPath);
    await dbManager.initialize();
    const frameManager = new FrameManager(dbManager);
    this.monitor = new SessionMonitor(
      frameManager,
      dbManager,
      this.config.projectRoot,
      {
        contextWarningThreshold: 0.6,
        contextCriticalThreshold: 0.7,
        contextAutoSaveThreshold: 0.85,
        idleTimeoutMinutes: 5,
        autoSaveLedger: this.config.autoTriggers.onContextCritical,
        autoGenerateHandoff: this.config.autoTriggers.onSessionIdle,
        sessionEndHandoff: this.config.autoTriggers.onSessionEnd
      }
    );
    this.registerEventHandlers();
    await this.installClaudeHooks();
    await this.monitor.start();
    this.isActive = true;
    console.log("\u2705 Claude Code lifecycle hooks initialized");
  }
  /**
   * Register event handlers for monitor events
   */
  registerEventHandlers() {
    if (!this.monitor) return;
    this.monitor.on("context:warning", (data) => {
      console.log(`\u26A0\uFE0F Context at ${Math.round(data.percentage * 100)}%`);
    });
    this.monitor.on("context:high", async (data) => {
      if (this.config.autoTriggers.onContextHigh) {
        console.log("\u{1F7E1} High context - preparing auto-save");
        await this.executeHook("on-context-high", data);
      }
    });
    this.monitor.on("context:ledger_saved", (data) => {
      console.log(`\u2705 Ledger saved (${data.compression}x compression)`);
      console.log("\u{1F4A1} You can now safely use /clear");
    });
    this.monitor.on("handoff:generated", (data) => {
      console.log(`\u{1F4CB} Handoff saved (trigger: ${data.trigger})`);
    });
  }
  /**
   * Install hooks into Claude Code configuration
   */
  async installClaudeHooks() {
    await fs.mkdir(this.config.claudeHooksPath, { recursive: true });
    await this.installHook(
      "on-message-submit",
      `
#!/bin/bash
# StackMemory Context Monitor Hook
# Monitors token usage and triggers auto-save when needed

# Get estimated token count from Claude (if available)
TOKEN_COUNT=\${CLAUDE_TOKEN_COUNT:-0}
MAX_TOKENS=\${CLAUDE_MAX_TOKENS:-100000}

if [ "$TOKEN_COUNT" -gt 0 ]; then
  USAGE=$((TOKEN_COUNT * 100 / MAX_TOKENS))
  
  if [ "$USAGE" -gt 85 ]; then
    echo "\u{1F534} Critical: Context at \${USAGE}% - Auto-saving..."
    stackmemory clear --save > /dev/null 2>&1
    echo "\u2705 Ledger saved. Consider using /clear"
  elif [ "$USAGE" -gt 70 ]; then
    echo "\u26A0\uFE0F Warning: Context at \${USAGE}%"
    echo "\u{1F4A1} Run: stackmemory clear --save"
  fi
fi

# Update activity timestamp
stackmemory monitor --activity 2>/dev/null || true
`
    );
    await this.installHook(
      "on-session-end",
      `
#!/bin/bash
# StackMemory Session End Hook
# Generates handoff document when session ends

echo "\u{1F4E6} Saving session state..."

# Generate handoff
stackmemory handoff --generate > /dev/null 2>&1 && echo "\u2705 Handoff saved"

# Save ledger if context is significant
CONTEXT_STATUS=$(stackmemory clear --check 2>/dev/null | grep -o '[0-9]\\+%' | head -1 | tr -d '%')
if [ "\${CONTEXT_STATUS:-0}" -gt 30 ]; then
  stackmemory clear --save > /dev/null 2>&1 && echo "\u2705 Continuity ledger saved"
fi

echo "\u{1F44B} Session state preserved for next time"
`
    );
    await this.installHook(
      "on-command-clear",
      `
#!/bin/bash
# StackMemory Clear Interceptor
# Saves state before /clear command

echo "\u{1F504} Preparing for /clear..."

# Save continuity ledger
stackmemory clear --save > /dev/null 2>&1
echo "\u2705 Continuity ledger saved"

# Generate quick handoff
stackmemory handoff --generate > /dev/null 2>&1
echo "\u2705 Handoff document saved"

echo "\u2705 Ready for /clear - context will be restored automatically"
echo "\u{1F4A1} After /clear, run: stackmemory clear --restore"
`
    );
    await this.installHook(
      "on-idle-5min",
      `
#!/bin/bash
# StackMemory Idle Detector
# Generates handoff after 5 minutes of inactivity

echo "\u23F8\uFE0F Session idle - generating handoff..."
stackmemory handoff --generate > /dev/null 2>&1
echo "\u2705 Handoff saved. Ready to resume anytime."
`
    );
  }
  /**
   * Install a specific hook script
   */
  async installHook(name, script) {
    const hookPath = path.join(this.config.claudeHooksPath, name);
    this.hookScripts.set(name, script);
    await fs.writeFile(hookPath, script.trim(), { mode: 493 });
    await fs.chmod(hookPath, 493);
  }
  /**
   * Execute a hook with context
   */
  async executeHook(hookName, context) {
    const hookPath = path.join(this.config.claudeHooksPath, hookName);
    try {
      await fs.access(hookPath);
      const { exec } = await import("child_process");
      const { promisify } = await import("util");
      const execAsync = promisify(exec);
      const env = {
        ...process.env,
        STACKMEMORY_CONTEXT: JSON.stringify(context),
        STACKMEMORY_PROJECT: this.config.projectRoot
      };
      const { stdout, stderr } = await execAsync(hookPath, { env });
      if (stdout) console.log(stdout);
      if (stderr) console.error(stderr);
    } catch (error) {
      console.debug(`Hook ${hookName} not found or failed:`, error);
    }
  }
  /**
   * Stop monitoring and cleanup
   */
  async stop() {
    if (this.monitor) {
      await this.monitor.stop();
    }
    this.isActive = false;
    console.log("\u{1F6D1} Claude Code lifecycle hooks stopped");
  }
  /**
   * Get current status
   */
  getStatus() {
    return {
      isActive: this.isActive,
      monitorStatus: this.monitor?.getStatus(),
      config: this.config,
      installedHooks: Array.from(this.hookScripts.keys())
    };
  }
}
let globalInstance;
async function initializeClaudeHooks(projectRoot) {
  if (!projectRoot) {
    projectRoot = process.cwd();
  }
  if (!globalInstance) {
    globalInstance = new ClaudeCodeLifecycleHooks({
      projectRoot,
      autoTriggers: {
        onContextHigh: true,
        onContextCritical: true,
        onSessionIdle: true,
        onSessionEnd: true,
        onClearCommand: true
      }
    });
    await globalInstance.initialize();
  }
  return globalInstance;
}
function getClaudeHooks() {
  return globalInstance;
}
async function stopClaudeHooks() {
  if (globalInstance) {
    await globalInstance.stop();
    globalInstance = void 0;
  }
}
export {
  ClaudeCodeLifecycleHooks,
  getClaudeHooks,
  initializeClaudeHooks,
  stopClaudeHooks
};
//# sourceMappingURL=lifecycle-hooks.js.map
