/**
 * Tests for Claude client utilities
 */

import { describe, it, expect } from 'vitest';
import {
  detectRuleIndex,
  isRegexSafe,
} from '../infra/claude/client.js';

describe('isRegexSafe', () => {
  it('should accept simple patterns', () => {
    expect(isRegexSafe('\\[DONE\\]')).toBe(true);
    expect(isRegexSafe('hello')).toBe(true);
    expect(isRegexSafe('^start')).toBe(true);
  });

  it('should reject patterns that are too long', () => {
    const longPattern = 'a'.repeat(201);
    expect(isRegexSafe(longPattern)).toBe(false);
  });

  it('should reject ReDoS patterns', () => {
    expect(isRegexSafe('(.*)*')).toBe(false);
    expect(isRegexSafe('(.+)+')).toBe(false);
    expect(isRegexSafe('(a|b)+')).toBe(false);
  });
});

describe('detectRuleIndex', () => {
  it('should detect [PLAN:1] as index 0', () => {
    expect(detectRuleIndex('Analysis complete.\n[PLAN:1]', 'plan')).toBe(0);
  });

  it('should detect [PLAN:2] as index 1', () => {
    expect(detectRuleIndex('Question answered.\n[PLAN:2]', 'plan')).toBe(1);
  });

  it('should detect [PLAN:3] as index 2', () => {
    expect(detectRuleIndex('[PLAN:3]\n\nBlocked.', 'plan')).toBe(2);
  });

  it('should be case insensitive', () => {
    expect(detectRuleIndex('[plan:1]', 'plan')).toBe(0);
    expect(detectRuleIndex('[Plan:2]', 'plan')).toBe(1);
  });

  it('should match movement name case-insensitively', () => {
    expect(detectRuleIndex('[IMPLEMENT:1]', 'implement')).toBe(0);
    expect(detectRuleIndex('[REVIEW:2]', 'review')).toBe(1);
  });

  it('should return -1 when no match', () => {
    expect(detectRuleIndex('No tags here.', 'plan')).toBe(-1);
  });

  it('should return -1 for [PLAN:0] (invalid)', () => {
    expect(detectRuleIndex('[PLAN:0]', 'plan')).toBe(-1);
  });

  it('should return -1 for wrong step name', () => {
    expect(detectRuleIndex('[REVIEW:1]', 'plan')).toBe(-1);
  });

  it('should handle step names with hyphens', () => {
    expect(detectRuleIndex('[AI_REVIEW:1]', 'ai_review')).toBe(0);
    expect(detectRuleIndex('[SECURITY_FIX:2]', 'security_fix')).toBe(1);
  });

  it('should detect last occurrence when multiple tags exist', () => {
    const content = 'Previous: [AI_REVIEW:1]\n\nActual result:\n[AI_REVIEW:2]';
    expect(detectRuleIndex(content, 'ai_review')).toBe(1);
  });

  it('should detect last match with multiple occurrences', () => {
    expect(detectRuleIndex('[PLAN:1] then [PLAN:2] finally [PLAN:3]', 'plan')).toBe(2);
  });
});
