/**
 * Security Test Suite
 * 
 * Comprehensive security testing per DoD/MilSpec requirements:
 * - NIST SP 800-53: CA-8 (Penetration Testing), RA-5 (Vulnerability Scanning)
 * 
 * Test categories:
 * - Authentication and authorization
 * - Input validation
 * - Cryptographic functions
 * - Session management
 * - Error handling
 * - Logging and monitoring
 */

import { describe, it, expect } from 'vitest'
import { validateSecret, SecretValidationError } from '../../lib/secret-validation'
import { encrypt, decrypt, generateKey, hash, hmac } from '../../lib/crypto'
import { classifyData, generateMarkings } from '../../services/data-classification'

describe('Secret Validation', () => {
  it('should reject insecure default secrets', () => {
    expect(() => {
      validateSecret('your-secret-key-change-in-production', 'TEST_SECRET')
    }).toThrow(SecretValidationError)
  })

  it('should reject short secrets', () => {
    expect(() => {
      validateSecret('short', 'TEST_SECRET')
    }).toThrow(SecretValidationError)
  })

  it('should reject secrets without required complexity', () => {
    expect(() => {
      validateSecret('alllowercaselettersonly', 'TEST_SECRET')
    }).toThrow(SecretValidationError)
  })

  it('should accept valid secrets', () => {
    expect(() => {
      validateSecret('ValidSecret123!@#', 'TEST_SECRET', { minLength: 16 })
    }).not.toThrow()
  })
})

describe('Cryptographic Functions', () => {
  it('should encrypt and decrypt data correctly', () => {
    const key = generateKey()
    const plaintext = 'Sensitive data to encrypt'
    
    const encrypted = encrypt(plaintext, key)
    const decrypted = decrypt(encrypted.encrypted, key, encrypted.iv, encrypted.authTag)
    
    expect(decrypted).toBe(plaintext)
  })

  it('should generate consistent hashes', () => {
    const data = 'test data'
    const hash1 = hash(data)
    const hash2 = hash(data)
    
    expect(hash1).toBe(hash2)
    expect(hash1).toHaveLength(64) // SHA-256 produces 64 hex characters
  })

  it('should generate HMAC correctly', () => {
    const key = generateKey()
    const data = 'test data'
    const hmac1 = hmac(data, key)
    const hmac2 = hmac(data, key)
    
    expect(hmac1).toBe(hmac2)
    expect(hmac1).toHaveLength(64) // SHA-256 HMAC produces 64 hex characters
  })
})

describe('Data Classification', () => {
  it('should classify credentials as SECRET', () => {
    const level = classifyData('password: secret123')
    expect(level).toBe('SECRET')
  })

  it('should classify PII as CUI', () => {
    const level = classifyData('SSN: 123-45-6789')
    expect(level).toBe('CUI')
  })

  it('should default to UNCLASSIFIED for unknown content', () => {
    const level = classifyData('Regular document content')
    expect(level).toBe('UNCLASSIFIED')
  })

  it('should generate correct markings', () => {
    const markings = generateMarkings('SECRET', 'CREDENTIALS')
    expect(markings).toContain('SECRET')
  })
})

describe('Input Validation', () => {
  it('should sanitize script tags', () => {
    const { sanitizeInput } = require('../../middleware/security')
    const malicious = '<script>alert("xss")</script>'
    const sanitized = sanitizeInput(malicious)
    
    expect(sanitized).not.toContain('<script>')
  })

  it('should sanitize javascript: protocol', () => {
    const { sanitizeInput } = require('../../middleware/security')
    const malicious = 'javascript:alert("xss")'
    const sanitized = sanitizeInput(malicious)
    
    expect(sanitized).not.toContain('javascript:')
  })
})

