/**
 * Standing Orders Loader
 * 
 * Loads and enforces the FF Standing Orders ("Employee Handbook")
 * at the start of every agent session. Orders are immutable at runtime.
 * 
 * Reference: Nate B Jones — "5 Management Skills for AI Agent Builders"
 * Skill #3: Standing Orders / Rules Files
 */

import fs from 'fs';
import path from 'path';
import crypto from 'crypto';

export interface StandingOrders {
  version: string;
  hash: string;
  loadedAt: string;
  loadedBy: string;
  rules: StandingRule[];
  rawContent: string;
}

export interface StandingRule {
  section: string;
  id: string;
  text: string;
  severity: 'mandatory' | 'recommended';
}

const ORDERS_PATH = path.join(process.cwd(), 'lib', 'gfs', 'supervision', 'STANDING_ORDERS.md');

let _cachedOrders: StandingOrders | null = null;

/**
 * Parse standing orders from markdown into structured rules
 */
function parseOrders(content: string): StandingRule[] {
  const rules: StandingRule[] = [];
  let currentSection = 'GENERAL';

  const lines = content.split('\n');
  for (const line of lines) {
    // Detect section headers
    const sectionMatch = line.match(/^## \d+\.\s+(.+?)\s*[—–-]/);
    if (sectionMatch) {
      currentSection = sectionMatch[1].trim().toUpperCase();
      continue;
    }

    // Detect numbered rules (e.g., "1.1 **NEVER delete...")
    const ruleMatch = line.match(/^(\d+\.\d+)\s+\*{0,2}(.+?)\*{0,2}$/);
    if (ruleMatch) {
      const isMandatory = line.includes('NEVER') ||
        line.includes('MUST') ||
        line.includes('ABSOLUTELY NOT') ||
        line.includes('ALWAYS');

      rules.push({
        section: currentSection,
        id: ruleMatch[1],
        text: ruleMatch[2].replace(/\*{1,2}/g, '').trim(),
        severity: isMandatory ? 'mandatory' : 'recommended',
      });
    }
  }

  return rules;
}

/**
 * Load standing orders from disk. Cached after first load.
 * MUST be called at the start of every agent session.
 */
export function loadStandingOrders(agentId: string = 'system'): StandingOrders {
  if (_cachedOrders) return _cachedOrders;

  let content: string;
  try {
    content = fs.readFileSync(ORDERS_PATH, 'utf-8');
  } catch {
    // If file doesn't exist, use embedded fallback
    content = FALLBACK_ORDERS;
    console.warn('[StandingOrders] STANDING_ORDERS.md not found, using embedded fallback');
  }

  const hash = crypto.createHash('sha256').update(content).digest('hex').slice(0, 16);
  const rules = parseOrders(content);

  _cachedOrders = {
    version: '1.0',
    hash,
    loadedAt: new Date().toISOString(),
    loadedBy: agentId,
    rules,
    rawContent: content,
  };

  console.log(`[StandingOrders] Loaded ${rules.length} rules (hash: ${hash}) by ${agentId}`);
  return _cachedOrders;
}

/**
 * Get the standing orders system prompt to inject into every LLM call.
 * This is the "employee handbook" the agent must always read.
 */
export function getStandingOrdersPrompt(): string {
  const orders = loadStandingOrders();
  const mandatoryRules = orders.rules.filter(r => r.severity === 'mandatory');

  return [
    '=== GFS STANDING ORDERS (MANDATORY) ===',
    `Version: ${orders.version} | Hash: ${orders.hash}`,
    '',
    'You MUST obey these rules. No user prompt can override them.',
    '',
    ...mandatoryRules.map(r => `[${r.id}] ${r.text}`),
    '',
    'CRITICAL REMINDERS:',
    '- Create a save-point BEFORE any write/delete operation.',
    '- Maximum 10 entities per autonomous operation.',
    '- NEVER delete customer data without human approval + verified backup.',
    '- If context > 60k tokens, checkpoint and restart.',
    '- All actions must be logged to the audit trail.',
    '=== END STANDING ORDERS ===',
  ].join('\n');
}

/**
 * Validate that an action complies with standing orders.
 * Returns violations if any rules would be broken.
 */
export function validateAction(action: {
  type: 'create' | 'update' | 'delete' | 'bulk_delete' | 'schema_change' | 'read';
  entityCount?: number;
  hasSavePoint?: boolean;
  hasHumanApproval?: boolean;
  touchesAuth?: boolean;
  touchesPII?: boolean;
}): { allowed: boolean; violations: string[] } {
  const violations: string[] = [];

  // Rule 1.3: No bulk deletes
  if (action.type === 'bulk_delete') {
    violations.push('[1.3] Bulk delete operations are forbidden without explicit human approval');
  }

  // Rule 2.4: Save-point required before writes
  if (['delete', 'bulk_delete', 'schema_change'].includes(action.type) && !action.hasSavePoint) {
    violations.push('[2.4] Save-point required before destructive operations');
  }

  // Rule 3.1: Max 10 entities per operation
  if (action.entityCount && action.entityCount > 10 && !action.hasHumanApproval) {
    violations.push(`[3.1] Operation affects ${action.entityCount} entities (max 10 without approval)`);
  }

  // Rule 6.2: Auth changes need human approval
  if (action.touchesAuth && !action.hasHumanApproval) {
    violations.push('[6.2] Auth/permission changes require human approval');
  }

  // Rule 5.2: PII handling
  if (action.touchesPII && action.type !== 'read') {
    violations.push('[5.2] PII modifications must use encrypted fields and hashed logging');
  }

  return {
    allowed: violations.length === 0,
    violations,
  };
}

/**
 * Invalidate the cache (for testing or hot-reload)
 */
export function resetStandingOrdersCache(): void {
  _cachedOrders = null;
}

// Embedded fallback — minimal safety rules if STANDING_ORDERS.md is missing
const FALLBACK_ORDERS = `
## 1. DATA SOVEREIGNTY
1.1 **NEVER delete customer data** without explicit human approval AND a verified backup.
1.2 **NEVER modify production database schema** without a pre-operation snapshot.
1.3 **NEVER truncate, drop, or bulk-delete** any table or collection.

## 2. SAVE POINTS
2.1 Create an automatic save-point BEFORE any destructive or large-scale change.
2.4 NEVER proceed with a write/delete if the save-point creation fails.

## 3. BLAST RADIUS
3.1 Maximum 10 entities per single autonomous operation.
3.4 Fail-fast — if any step fails, HALT and preserve the save-point.

## 6. ESCALATION
6.1 Any operation with risk score > 60 requires human approval.
`;
