import { EventEmitter } from 'events';
import { createHash, randomBytes } from 'crypto';
import { SecurityHardeningManager } from './securityHardeningManager.js';
import fs from 'fs/promises';
import path from 'path';

/**
 * Advanced License Enforcement Engine
 * Real-time license monitoring, enforcement, and security protection
 */
export class LicenseEnforcementEngine extends EventEmitter {
  constructor(licenseValidator) {
    super();

    this.licenseValidator = licenseValidator;
    this.securityHardening = new SecurityHardeningManager();
    this.enforcementRules = new Map();
    this.violationHistory = new Map();
    this.securityMetrics = new Map();
    this.realTimeMonitoring = new Map();
    
    // Enforcement configuration
    this.enforcementConfig = {
      strictMode: true,
      realTimeValidation: true,
      violationThreshold: 3,
      lockoutDuration: 3600000, // 1 hour
      securityScanInterval: 60000, // 1 minute
      heartbeatInterval: 30000, // 30 seconds
      tamperDetection: true,
      networkValidation: true
    };
    
    // Enforcement rules
    this.enforcementRules = new Map([
      ['license_required', {
        name: 'Valid License Required',
        severity: 'CRITICAL',
        action: 'block_all_operations',
        description: 'All MCP operations require valid license'
      }],
      ['bridge_required', {
        name: 'ZAI Bridge Required',
        severity: 'HIGH',
        action: 'block_ai_operations',
        description: 'AI-to-AI operations require ZAI Bridge connection'
      }],
      ['device_authorized', {
        name: 'Device Authorization Required',
        severity: 'HIGH',
        action: 'block_unauthorized_device',
        description: 'Device must be authorized for license'
      }],
      ['feature_access', {
        name: 'Feature Access Control',
        severity: 'MEDIUM',
        action: 'block_premium_features',
        description: 'Premium features require appropriate license tier'
      }],
      ['usage_limits', {
        name: 'Usage Limits Enforcement',
        severity: 'MEDIUM',
        action: 'throttle_requests',
        description: 'Enforce license usage limits'
      }],
      ['tamper_detection', {
        name: 'Tamper Detection',
        severity: 'CRITICAL',
        action: 'immediate_lockout',
        description: 'Detect and prevent license tampering'
      }]
    ]);
    
    // Security metrics tracking
    this.securityMetrics = new Map([
      ['license_validations', { count: 0, failures: 0, lastFailure: null }],
      ['bridge_connections', { count: 0, failures: 0, lastFailure: null }],
      ['device_authorizations', { count: 0, failures: 0, lastFailure: null }],
      ['tamper_attempts', { count: 0, detected: 0, lastAttempt: null }],
      ['violation_attempts', { count: 0, blocked: 0, lastViolation: null }]
    ]);
    
    this.initializeEnforcement();
    this.startRealTimeMonitoring();
    
    console.log('🛡️ Advanced License Enforcement Engine initialized');
  }

  /**
   * Initialize enforcement engine
   */
  initializeEnforcement() {
    // Set up license validator event listeners
    this.licenseValidator.on('licenseValidated', (license) => {
      this.handleLicenseValidated(license);
    });
    
    this.licenseValidator.on('licenseValidationFailed', (error) => {
      this.handleLicenseValidationFailed(error);
    });
    
    this.licenseValidator.on('bridgeConnected', (connection) => {
      this.handleBridgeConnected(connection);
    });
    
    this.licenseValidator.on('licenseInvalidated', (validation) => {
      this.handleLicenseInvalidated(validation);
    });
    
    console.log('🛡️ License enforcement rules initialized');
  }

  /**
   * Enforce license requirements for operation
   */
  async enforceOperation(operation, context = {}) {
    const enforcementId = this.generateEnforcementId();
    
    const enforcement = {
      id: enforcementId,
      timestamp: Date.now(),
      operation,
      context,
      allowed: false,
      violations: [],
      actions: [],
      securityLevel: 'NORMAL'
    };
    
    try {
      console.log(`🛡️ Enforcing license for operation: ${operation}`);
      
      // Step 1: Check license validity
      const licenseCheck = await this.checkLicenseRequirement(operation, context);
      if (!licenseCheck.valid) {
        enforcement.violations.push({
          rule: 'license_required',
          severity: 'CRITICAL',
          message: licenseCheck.reason
        });
      }
      
      // Step 2: Check bridge requirement
      const bridgeCheck = await this.checkBridgeRequirement(operation, context);
      if (!bridgeCheck.valid) {
        enforcement.violations.push({
          rule: 'bridge_required',
          severity: 'HIGH',
          message: bridgeCheck.reason
        });
      }
      
      // Step 3: Check device authorization
      const deviceCheck = await this.checkDeviceAuthorization(operation, context);
      if (!deviceCheck.valid) {
        enforcement.violations.push({
          rule: 'device_authorized',
          severity: 'HIGH',
          message: deviceCheck.reason
        });
      }
      
      // Step 4: Check feature access
      const featureCheck = await this.checkFeatureAccess(operation, context);
      if (!featureCheck.valid) {
        enforcement.violations.push({
          rule: 'feature_access',
          severity: 'MEDIUM',
          message: featureCheck.reason
        });
      }
      
      // Step 5: Check usage limits
      const usageCheck = await this.checkUsageLimits(operation, context);
      if (!usageCheck.valid) {
        enforcement.violations.push({
          rule: 'usage_limits',
          severity: 'MEDIUM',
          message: usageCheck.reason
        });
      }
      
      // Step 6: Tamper detection
      const tamperCheck = await this.checkTamperDetection(operation, context);
      if (!tamperCheck.valid) {
        enforcement.violations.push({
          rule: 'tamper_detection',
          severity: 'CRITICAL',
          message: tamperCheck.reason
        });
        enforcement.securityLevel = 'CRITICAL';
      }
      
      // Determine if operation is allowed
      const criticalViolations = enforcement.violations.filter(v => v.severity === 'CRITICAL');
      const highViolations = enforcement.violations.filter(v => v.severity === 'HIGH');
      
      if (criticalViolations.length === 0 && highViolations.length === 0) {
        enforcement.allowed = true;
      } else {
        enforcement.allowed = false;
        
        // Execute enforcement actions
        for (const violation of enforcement.violations) {
          const action = await this.executeEnforcementAction(violation, enforcement);
          enforcement.actions.push(action);
        }
      }
      
      // Update security metrics
      this.updateMetric('enforcement_operations', enforcement.allowed ? 'success' : 'failure');
      
      // Log enforcement result
      if (enforcement.allowed) {
        console.log(`✅ Operation allowed: ${operation}`);
      } else {
        console.warn(`❌ Operation blocked: ${operation} (${enforcement.violations.length} violations)`);
        this.emit('operationBlocked', enforcement);
      }
      
      this.emit('operationEnforced', enforcement);
      
      return enforcement;
      
    } catch (error) {
      enforcement.violations.push({
        rule: 'enforcement_error',
        severity: 'CRITICAL',
        message: `Enforcement error: ${error.message}`
      });
      
      console.error('❌ License enforcement error:', error.message);
      return enforcement;
    }
  }

  /**
   * Check license requirement
   */
  async checkLicenseRequirement(operation, context) {
    // 🔐 CRITICAL: Perform real-time license validation for each operation
    try {
      console.log(`🔐 Real-time license validation for operation: ${operation}`);
      const validation = await this.licenseValidator.validateMCPStartup();

      if (!validation.canStart || !validation.requirements.licenseValid) {
        this.updateMetric('license_validations', 'failure');
        console.log(`❌ License validation failed for ${operation}: ${validation.errors.join(', ')}`);
        return {
          valid: false,
          reason: `License validation failed: ${validation.errors.join(', ')}`
        };
      }

      this.updateMetric('license_validations', 'success');
      console.log(`✅ License validation passed for ${operation}`);
      return { valid: true };

    } catch (error) {
      this.updateMetric('license_validations', 'failure');
      console.log(`❌ License validation error for ${operation}: ${error.message}`);
      return {
        valid: false,
        reason: `License validation error: ${error.message}`
      };
    }
  }

  /**
   * Check bridge requirement
   */
  async checkBridgeRequirement(operation, context) {
    const licenseStatus = this.licenseValidator.getLicenseStatus();
    
    // AI-to-AI operations require bridge
    const aiOperations = [
      'activate_infinite_loop',
      'get_ai_prompts',
      'acknowledge_agent_response'
    ];
    
    if (aiOperations.includes(operation) && !licenseStatus.bridgeConnected) {
      this.updateMetric('bridge_connections', 'failure');
      return {
        valid: false,
        reason: 'ZAI Bridge connection required for AI-to-AI operations'
      };
    }
    
    this.updateMetric('bridge_connections', 'success');
    return { valid: true };
  }

  /**
   * Check device authorization
   */
  async checkDeviceAuthorization(operation, context) {
    const licenseStatus = this.licenseValidator.getLicenseStatus();
    
    if (licenseStatus.isValid && licenseStatus.license) {
      const license = licenseStatus.license;
      
      // Check device limit
      if (license.deviceLimit && license.deviceCount >= license.deviceLimit) {
        this.updateMetric('device_authorizations', 'failure');
        return {
          valid: false,
          reason: `Device limit exceeded: ${license.deviceCount}/${license.deviceLimit}`
        };
      }
    }
    
    this.updateMetric('device_authorizations', 'success');
    return { valid: true };
  }

  /**
   * Check feature access
   */
  async checkFeatureAccess(operation, context) {
    const licenseStatus = this.licenseValidator.getLicenseStatus();
    
    if (licenseStatus.isValid && licenseStatus.license) {
      const license = licenseStatus.license;
      const features = license.features || [];
      
      // Check if operation requires premium features
      const premiumOperations = {
        'activate_infinite_loop': 'ai_to_ai_communication',
        'get_ai_prompts': 'ai_to_ai_communication',
        'acknowledge_agent_response': 'ai_to_ai_communication'
      };
      
      const requiredFeature = premiumOperations[operation];
      if (requiredFeature && !features.includes(requiredFeature)) {
        return {
          valid: false,
          reason: `Feature not included in license: ${requiredFeature}`
        };
      }
    }
    
    return { valid: true };
  }

  /**
   * Check usage limits
   */
  async checkUsageLimits(operation, context) {
    const licenseStatus = this.licenseValidator.getLicenseStatus();
    
    if (licenseStatus.isValid && licenseStatus.license) {
      const license = licenseStatus.license;
      
      // Check monthly usage limits
      if (license.monthlyLimit) {
        const currentUsage = await this.getCurrentMonthlyUsage();
        
        if (currentUsage >= license.monthlyLimit) {
          return {
            valid: false,
            reason: `Monthly usage limit exceeded: ${currentUsage}/${license.monthlyLimit}`
          };
        }
      }
    }
    
    return { valid: true };
  }

  /**
   * Check tamper detection
   */
  async checkTamperDetection(operation, context) {
    try {
      // Check for license file tampering
      const licenseStatus = this.licenseValidator.getLicenseStatus();
      
      if (licenseStatus.isValid && licenseStatus.license) {
        const license = licenseStatus.license;
        
        // Verify license signature
        const expectedSignature = this.calculateLicenseSignature(license);
        if (license.signature && license.signature !== expectedSignature) {
          this.updateMetric('tamper_attempts', 'detected');
          return {
            valid: false,
            reason: 'License tampering detected - signature mismatch'
          };
        }
        
        // Check for time manipulation
        const systemTime = Date.now();
        const licenseTime = license.issuedAt;
        
        if (systemTime < licenseTime) {
          this.updateMetric('tamper_attempts', 'detected');
          return {
            valid: false,
            reason: 'System time manipulation detected'
          };
        }
      }
      
      return { valid: true };
      
    } catch (error) {
      this.updateMetric('tamper_attempts', 'detected');
      return {
        valid: false,
        reason: `Tamper detection error: ${error.message}`
      };
    }
  }

  /**
   * Execute enforcement action
   */
  async executeEnforcementAction(violation, enforcement) {
    const rule = this.enforcementRules.get(violation.rule);
    
    if (!rule) {
      return {
        action: 'unknown',
        executed: false,
        reason: 'Unknown enforcement rule'
      };
    }
    
    const action = {
      rule: violation.rule,
      action: rule.action,
      executed: false,
      timestamp: Date.now(),
      details: {}
    };
    
    try {
      switch (rule.action) {
        case 'block_all_operations':
          action.details = await this.blockAllOperations(enforcement);
          action.executed = true;
          break;
          
        case 'block_ai_operations':
          action.details = await this.blockAIOperations(enforcement);
          action.executed = true;
          break;
          
        case 'block_unauthorized_device':
          action.details = await this.blockUnauthorizedDevice(enforcement);
          action.executed = true;
          break;
          
        case 'block_premium_features':
          action.details = await this.blockPremiumFeatures(enforcement);
          action.executed = true;
          break;
          
        case 'throttle_requests':
          action.details = await this.throttleRequests(enforcement);
          action.executed = true;
          break;
          
        case 'immediate_lockout':
          action.details = await this.immediateLockout(enforcement);
          action.executed = true;
          break;
          
        default:
          action.details = { message: 'No action handler defined' };
      }
      
      console.log(`🛡️ Enforcement action executed: ${rule.action}`);
      
    } catch (error) {
      action.details = { error: error.message };
      console.error(`❌ Enforcement action failed: ${rule.action} - ${error.message}`);
    }
    
    return action;
  }

  /**
   * Start real-time monitoring
   */
  startRealTimeMonitoring() {
    // License heartbeat monitoring
    setInterval(() => {
      this.performLicenseHeartbeat();
    }, this.enforcementConfig.heartbeatInterval);
    
    // Security scan monitoring
    setInterval(() => {
      this.performSecurityScan();
    }, this.enforcementConfig.securityScanInterval);
    
    console.log('🛡️ Real-time license monitoring started');
  }

  /**
   * Perform license heartbeat check
   */
  async performLicenseHeartbeat() {
    try {
      const licenseStatus = this.licenseValidator.getLicenseStatus();
      
      if (licenseStatus.isValid) {
        // Verify license is still valid
        await this.licenseValidator.validateMCPStartup();
        
        this.realTimeMonitoring.set('last_heartbeat', {
          timestamp: Date.now(),
          status: 'healthy',
          license: licenseStatus.license?.licenseId
        });
      } else {
        this.realTimeMonitoring.set('last_heartbeat', {
          timestamp: Date.now(),
          status: 'invalid',
          error: licenseStatus.validationErrors
        });
        
        this.emit('licenseHeartbeatFailed', licenseStatus);
      }
    } catch (error) {
      console.error('❌ License heartbeat failed:', error.message);
    }
  }

  /**
   * Perform security scan
   */
  async performSecurityScan() {
    try {
      const scanResults = {
        timestamp: Date.now(),
        threats: [],
        warnings: [],
        status: 'clean'
      };
      
      // Check for suspicious activity
      const violations = Array.from(this.violationHistory.values());
      const recentViolations = violations.filter(v => 
        Date.now() - v.timestamp < 300000 // Last 5 minutes
      );
      
      if (recentViolations.length > this.enforcementConfig.violationThreshold) {
        scanResults.threats.push({
          type: 'excessive_violations',
          count: recentViolations.length,
          severity: 'HIGH'
        });
        scanResults.status = 'threats_detected';
      }
      
      this.realTimeMonitoring.set('last_security_scan', scanResults);
      
      if (scanResults.threats.length > 0) {
        this.emit('securityThreatsDetected', scanResults);
      }
      
    } catch (error) {
      console.error('❌ Security scan failed:', error.message);
    }
  }

  /**
   * Utility methods
   */
  generateEnforcementId() {
    return 'ENF_' + Date.now() + '_' + randomBytes(4).toString('hex').toUpperCase();
  }
  
  updateMetric(metricName, type) {
    const metric = this.securityMetrics.get(metricName);
    if (metric) {
      metric.count++;
      if (type === 'failure' || type === 'detected') {
        metric.failures++;
        metric.lastFailure = Date.now();
      }
    }
  }
  
  calculateLicenseSignature(license) {
    const data = `${license.licenseId}${license.userId}${license.tier}${license.issuedAt}`;
    return createHash('sha256').update(data).digest('hex');
  }
  
  async getCurrentMonthlyUsage() {
    // Simplified usage tracking
    return Math.floor(Math.random() * 1000); // Simulate current usage
  }
  
  // Enforcement action implementations
  async blockAllOperations(enforcement) {
    return { blocked: true, message: 'All operations blocked due to license violation' };
  }
  
  async blockAIOperations(enforcement) {
    return { blocked: true, message: 'AI-to-AI operations blocked - bridge required' };
  }
  
  async blockUnauthorizedDevice(enforcement) {
    return { blocked: true, message: 'Device not authorized for this license' };
  }
  
  async blockPremiumFeatures(enforcement) {
    return { blocked: true, message: 'Premium features not included in license tier' };
  }
  
  async throttleRequests(enforcement) {
    return { throttled: true, delay: 5000, message: 'Request throttled due to usage limits' };
  }
  
  async immediateLockout(enforcement) {
    return { locked: true, duration: this.enforcementConfig.lockoutDuration, message: 'Immediate lockout due to security violation' };
  }
  
  /**
   * Event handlers for license validator events
   */
  handleLicenseValidated(license) {
    console.log('🛡️ License validated - enforcement active');
    this.updateMetric('license_validations', 'success');
  }

  handleLicenseValidationFailed(error) {
    console.log('🛡️ License validation failed - enforcement blocking operations');
    this.updateMetric('license_validations', 'failure');
  }

  handleBridgeConnected(connection) {
    console.log(`🛡️ Bridge connected - enforcement monitoring connection ${connection.id}`);
    this.updateMetric('bridge_connections', 'success');
  }

  handleLicenseInvalidated(validation) {
    console.log('🛡️ License invalidated - enforcement blocking operations');
    this.updateMetric('license_validations', 'invalidated');
  }

  /**
   * Get enforcement statistics
   */
  getEnforcementStats() {
    return {
      rules: {
        total: this.enforcementRules.size,
        active: Array.from(this.enforcementRules.values()).length
      },
      violations: {
        total: this.violationHistory.size,
        recent: Array.from(this.violationHistory.values()).filter(v =>
          Date.now() - v.timestamp < 3600000 // Last hour
        ).length
      },
      security: {
        metrics: Object.fromEntries(this.securityMetrics),
        monitoring: Object.fromEntries(this.realTimeMonitoring)
      },
      enforcement: {
        strictMode: this.enforcementConfig.strictMode,
        realTimeValidation: this.enforcementConfig.realTimeValidation
      }
    };
  }
}
