/**
 * HVAC Testing Framework - WordPress Security Helpers
 * 
 * Provides WordPress-specific security validation, nonce verification,
 * capability checking, and role management for secure testing.
 * 
 * Security Features:
 * - WordPress nonce validation and generation
 * - User capability and role verification
 * - CSRF protection for WordPress actions
 * - SQL injection prevention for WordPress queries
 * - Authentication state validation
 * 
 * @author Claude Code - Emergency Security Response
 * @version 1.0.0
 * @security CRITICAL - WordPress-specific security validation
 */

const { getCredentialManager } = require('./SecureCredentialManager');
const { getInputValidator } = require('./SecureInputValidator');
const { getCommandExecutor } = require('./SecureCommandExecutor');

class WordPressSecurityHelpers {
    constructor() {
        this.credentialManager = getCredentialManager();
        this.inputValidator = getInputValidator();
        this.commandExecutor = getCommandExecutor();
        this.nonceCache = new Map();
        this.capabilityCache = new Map();
        this.roleDefinitions = this.initializeRoleDefinitions();
    }

    /**
     * Initialize WordPress role definitions for HVAC system
     * @returns {Map} Role definitions with capabilities
     */
    initializeRoleDefinitions() {
        return new Map([
            ['administrator', {
                capabilities: [
                    'manage_options', 'edit_posts', 'edit_others_posts', 'publish_posts',
                    'edit_pages', 'edit_others_pages', 'publish_pages', 'delete_posts',
                    'delete_others_posts', 'delete_pages', 'delete_others_pages',
                    'manage_categories', 'manage_links', 'upload_files', 'edit_files',
                    'manage_users', 'install_plugins', 'activate_plugins', 'switch_themes',
                    'edit_themes', 'edit_users', 'delete_users', 'unfiltered_html',
                    'manage_hvac_system', 'manage_hvac_trainers', 'manage_hvac_events',
                    'view_hvac_reports', 'export_hvac_data', 'import_hvac_data'
                ],
                level: 10,
                description: 'Full system administrator'
            }],
            
            ['hvac_master_trainer', {
                capabilities: [
                    'read', 'edit_posts', 'publish_posts', 'upload_files',
                    'manage_hvac_trainers', 'manage_hvac_events', 'view_hvac_reports',
                    'export_hvac_data', 'import_hvac_data', 'edit_trainer_profiles',
                    'approve_trainers', 'create_announcements', 'manage_communications',
                    'view_pending_approvals', 'access_master_dashboard'
                ],
                level: 8,
                description: 'Master trainer with management capabilities'
            }],
            
            ['hvac_trainer', {
                capabilities: [
                    'read', 'edit_own_posts', 'upload_files',
                    'create_hvac_events', 'edit_own_events', 'manage_own_venues',
                    'manage_own_organizers', 'view_training_leads', 'edit_own_profile',
                    'access_trainer_dashboard', 'submit_for_approval'
                ],
                level: 5,
                description: 'Regular trainer with event management'
            }],
            
            ['subscriber', {
                capabilities: ['read'],
                level: 0,
                description: 'Basic read-only access'
            }]
        ]);
    }

    /**
     * Verify WordPress nonce for CSRF protection
     * @param {string} nonce - Nonce value to verify
     * @param {string} action - Action the nonce was generated for
     * @param {Object} context - Additional context (user, timestamp, etc.)
     * @returns {Promise<Object>} Verification result
     */
    async verifyWordPressNonce(nonce, action, context = {}) {
        try {
            // Basic nonce format validation
            const validation = this.inputValidator.validate(nonce, 'wp_nonce');
            if (!validation.valid) {
                throw new Error(`Invalid nonce format: ${validation.error}`);
            }

            // Check nonce cache for recent verifications
            const cacheKey = `${nonce}-${action}`;
            if (this.nonceCache.has(cacheKey)) {
                const cached = this.nonceCache.get(cacheKey);
                if (Date.now() - cached.timestamp < 300000) { // 5 minutes
                    return { valid: true, cached: true, ...cached };
                }
                this.nonceCache.delete(cacheKey);
            }

            // Verify nonce via WordPress CLI
            const wpCommand = `eval "echo wp_verify_nonce('${nonce}', '${action}');"`;
            const result = await this.commandExecutor.executeWordPressCommand(wpCommand);
            
            const isValid = result.stdout.trim() === '1';
            
            // Cache result
            if (isValid) {
                this.nonceCache.set(cacheKey, {
                    valid: true,
                    action,
                    timestamp: Date.now(),
                    context
                });
            }

            await this.credentialManager.auditLogger('NONCE_VERIFICATION', {
                nonce: nonce.substring(0, 6) + '...',
                action,
                valid: isValid,
                context
            });

            return {
                valid: isValid,
                action,
                verified_at: new Date().toISOString()
            };

        } catch (error) {
            await this.credentialManager.auditLogger('NONCE_VERIFICATION_ERROR', {
                action,
                error: error.message,
                context
            });

            return {
                valid: false,
                error: error.message
            };
        }
    }

    /**
     * Generate WordPress nonce for an action
     * @param {string} action - Action to generate nonce for
     * @param {Object} context - Generation context
     * @returns {Promise<string>} Generated nonce
     */
    async generateWordPressNonce(action, context = {}) {
        try {
            const wpCommand = `eval "echo wp_create_nonce('${action}');"`;
            const result = await this.commandExecutor.executeWordPressCommand(wpCommand);
            
            const nonce = result.stdout.trim();
            
            // Validate generated nonce
            const validation = this.inputValidator.validate(nonce, 'wp_nonce');
            if (!validation.valid) {
                throw new Error('Generated nonce is invalid');
            }

            // Cache the generated nonce
            const cacheKey = `${nonce}-${action}`;
            this.nonceCache.set(cacheKey, {
                valid: true,
                action,
                timestamp: Date.now(),
                generated: true,
                context
            });

            await this.credentialManager.auditLogger('NONCE_GENERATED', {
                action,
                nonce: nonce.substring(0, 6) + '...',
                context
            });

            return nonce;

        } catch (error) {
            await this.credentialManager.auditLogger('NONCE_GENERATION_ERROR', {
                action,
                error: error.message,
                context
            });
            throw error;
        }
    }

    /**
     * Verify user has required capability
     * @param {number|string} userId - WordPress user ID or username
     * @param {string} capability - Required capability
     * @returns {Promise<Object>} Capability check result
     */
    async verifyUserCapability(userId, capability) {
        try {
            // Validate capability name
            const validation = this.inputValidator.validate(capability, 'wp_capability');
            if (!validation.valid) {
                throw new Error(`Invalid capability name: ${validation.error}`);
            }

            // Check capability cache
            const cacheKey = `${userId}-${capability}`;
            if (this.capabilityCache.has(cacheKey)) {
                const cached = this.capabilityCache.get(cacheKey);
                if (Date.now() - cached.timestamp < 600000) { // 10 minutes
                    return { ...cached, cached: true };
                }
                this.capabilityCache.delete(cacheKey);
            }

            // Get user data via WordPress CLI
            const userCommand = `user get ${userId} --fields=roles,allcaps --format=json`;
            const userResult = await this.commandExecutor.executeWordPressCommand(userCommand);
            
            const userData = JSON.parse(userResult.stdout);
            const hasCapability = userData.allcaps && userData.allcaps[capability] === true;

            // Cache result
            const result = {
                userId,
                capability,
                hasCapability,
                userRoles: userData.roles || [],
                timestamp: Date.now()
            };

            this.capabilityCache.set(cacheKey, result);

            await this.credentialManager.auditLogger('CAPABILITY_CHECK', {
                userId,
                capability,
                hasCapability,
                roles: userData.roles
            });

            return result;

        } catch (error) {
            await this.credentialManager.auditLogger('CAPABILITY_CHECK_ERROR', {
                userId,
                capability,
                error: error.message
            });

            return {
                userId,
                capability,
                hasCapability: false,
                error: error.message
            };
        }
    }

    /**
     * Verify user has required role
     * @param {number|string} userId - WordPress user ID or username
     * @param {string|Array} requiredRoles - Required role(s)
     * @returns {Promise<Object>} Role verification result
     */
    async verifyUserRole(userId, requiredRoles) {
        try {
            const roles = Array.isArray(requiredRoles) ? requiredRoles : [requiredRoles];
            
            // Validate role names
            for (const role of roles) {
                const validation = this.inputValidator.validate(role, 'wp_role');
                if (!validation.valid) {
                    throw new Error(`Invalid role name: ${role}`);
                }
            }

            // Get user roles
            const userCommand = `user get ${userId} --fields=roles --format=json`;
            const result = await this.commandExecutor.executeWordPressCommand(userCommand);
            
            const userData = JSON.parse(result.stdout);
            const userRoles = userData.roles || [];
            
            // Check if user has any of the required roles
            const hasRequiredRole = roles.some(role => userRoles.includes(role));
            const matchedRoles = roles.filter(role => userRoles.includes(role));

            await this.credentialManager.auditLogger('ROLE_VERIFICATION', {
                userId,
                requiredRoles: roles,
                userRoles,
                hasRequiredRole,
                matchedRoles
            });

            return {
                userId,
                requiredRoles: roles,
                userRoles,
                hasRequiredRole,
                matchedRoles
            };

        } catch (error) {
            await this.credentialManager.auditLogger('ROLE_VERIFICATION_ERROR', {
                userId,
                requiredRoles,
                error: error.message
            });

            return {
                userId,
                requiredRoles,
                hasRequiredRole: false,
                error: error.message
            };
        }
    }

    /**
     * Validate WordPress database query for security
     * @param {string} query - SQL query to validate
     * @param {Object} context - Query context
     * @returns {Object} Query validation result
     */
    validateWordPressQuery(query, context = {}) {
        try {
            // Basic SQL injection prevention
            const sanitized = this.inputValidator.sanitize(query, 'sql');
            const validation = this.inputValidator.validate(sanitized, 'text_field', {
                maxLength: 10000
            });

            if (!validation.valid) {
                throw new Error(`Query validation failed: ${validation.error}`);
            }

            // WordPress-specific query validation
            this.validateWordPressQueryStructure(sanitized);

            this.credentialManager.auditLogger('QUERY_VALIDATION', {
                queryHash: require('crypto').createHash('sha256').update(query).digest('hex'),
                context,
                valid: true
            });

            return {
                valid: true,
                sanitizedQuery: sanitized
            };

        } catch (error) {
            this.credentialManager.auditLogger('QUERY_VALIDATION_ERROR', {
                error: error.message,
                context
            });

            return {
                valid: false,
                error: error.message
            };
        }
    }

    /**
     * Validate WordPress query structure
     * @param {string} query - Query to validate
     */
    validateWordPressQueryStructure(query) {
        const normalizedQuery = query.trim().toLowerCase();

        // Only allow SELECT queries for security
        if (!normalizedQuery.startsWith('select')) {
            throw new Error('Only SELECT queries are allowed');
        }

        // Block dangerous SQL operations
        const forbiddenOperations = [
            'drop', 'delete', 'truncate', 'alter', 'create',
            'insert', 'update', 'grant', 'revoke', 'exec',
            'execute', 'sp_', 'xp_'
        ];

        for (const operation of forbiddenOperations) {
            if (normalizedQuery.includes(operation)) {
                throw new Error(`SQL operation not allowed: ${operation}`);
            }
        }

        // Validate table names (must be WordPress tables)
        const wpTables = [
            'wp_posts', 'wp_users', 'wp_usermeta', 'wp_options',
            'wp_postmeta', 'wp_comments', 'wp_commentmeta',
            'wp_hvac_trainers', 'wp_hvac_events', 'wp_hvac_venues'
        ];

        // Extract table names from query
        const tableMatches = query.match(/from\s+(\w+)/gi);
        if (tableMatches) {
            for (const match of tableMatches) {
                const tableName = match.replace(/from\s+/i, '').trim();
                if (!wpTables.some(allowed => tableName.includes(allowed))) {
                    throw new Error(`Table not allowed: ${tableName}`);
                }
            }
        }
    }

    /**
     * Validate authentication state for a page/context
     * @param {Object} page - Playwright page object
     * @param {string} expectedRole - Expected user role
     * @returns {Promise<Object>} Authentication validation result
     */
    async validateAuthenticationState(page, expectedRole) {
        try {
            const currentUrl = page.url();
            
            // Check if on login page (indicates not authenticated)
            if (currentUrl.includes('/wp-login.php') || currentUrl.includes('/training-login/')) {
                return {
                    authenticated: false,
                    reason: 'Currently on login page',
                    currentUrl
                };
            }

            // Role-specific URL validation
            const roleUrlMap = {
                'hvac_master_trainer': /\/master-trainer\//,
                'hvac_trainer': /\/trainer\//,
                'administrator': /\/wp-admin\//
            };

            if (expectedRole && roleUrlMap[expectedRole]) {
                if (!roleUrlMap[expectedRole].test(currentUrl)) {
                    return {
                        authenticated: false,
                        reason: `URL does not match expected role: ${expectedRole}`,
                        currentUrl,
                        expectedPattern: roleUrlMap[expectedRole].toString()
                    };
                }
            }

            // Check for authentication indicators in page content
            const bodyText = await page.textContent('body').catch(() => '');
            
            // Negative indicators (suggests not authenticated)
            const negativeIndicators = [
                'please log in',
                'login required',
                'access denied',
                'unauthorized',
                'permission denied'
            ];

            for (const indicator of negativeIndicators) {
                if (bodyText.toLowerCase().includes(indicator)) {
                    return {
                        authenticated: false,
                        reason: `Negative authentication indicator found: ${indicator}`,
                        currentUrl
                    };
                }
            }

            // Positive indicators (suggests authenticated)
            const positiveIndicators = {
                'hvac_master_trainer': ['master dashboard', 'manage trainers', 'announcements'],
                'hvac_trainer': ['trainer dashboard', 'manage events', 'my venues'],
                'administrator': ['dashboard', 'admin', 'settings']
            };

            if (expectedRole && positiveIndicators[expectedRole]) {
                const hasPositiveIndicator = positiveIndicators[expectedRole]
                    .some(indicator => bodyText.toLowerCase().includes(indicator));

                if (!hasPositiveIndicator) {
                    return {
                        authenticated: 'uncertain',
                        reason: 'No positive authentication indicators found',
                        currentUrl
                    };
                }
            }

            await this.credentialManager.auditLogger('AUTHENTICATION_VALIDATION', {
                expectedRole,
                currentUrl,
                authenticated: true
            });

            return {
                authenticated: true,
                role: expectedRole,
                currentUrl
            };

        } catch (error) {
            await this.credentialManager.auditLogger('AUTHENTICATION_VALIDATION_ERROR', {
                expectedRole,
                error: error.message
            });

            return {
                authenticated: false,
                error: error.message
            };
        }
    }

    /**
     * Create CSRF-protected form data
     * @param {Object} formData - Form data to protect
     * @param {string} action - WordPress action
     * @returns {Promise<Object>} Protected form data
     */
    async createProtectedFormData(formData, action) {
        try {
            // Generate nonce for the action
            const nonce = await this.generateWordPressNonce(action);

            // Sanitize all form data
            const protectedData = {};
            for (const [key, value] of Object.entries(formData)) {
                if (typeof value === 'string') {
                    protectedData[key] = this.inputValidator.sanitize(value, 'wp_content');
                } else {
                    protectedData[key] = value;
                }
            }

            // Add security fields
            protectedData._wpnonce = nonce;
            protectedData.action = action;

            return {
                success: true,
                data: protectedData,
                nonce
            };

        } catch (error) {
            return {
                success: false,
                error: error.message
            };
        }
    }

    /**
     * Get role capabilities
     * @param {string} role - Role name
     * @returns {Object} Role information
     */
    getRoleCapabilities(role) {
        const roleInfo = this.roleDefinitions.get(role);
        if (!roleInfo) {
            return {
                exists: false,
                error: `Unknown role: ${role}`
            };
        }

        return {
            exists: true,
            role,
            capabilities: roleInfo.capabilities,
            level: roleInfo.level,
            description: roleInfo.description
        };
    }

    /**
     * Clean up caches (call periodically or on memory pressure)
     */
    cleanupCaches() {
        const now = Date.now();
        
        // Clean nonce cache (older than 5 minutes)
        for (const [key, value] of this.nonceCache) {
            if (now - value.timestamp > 300000) {
                this.nonceCache.delete(key);
            }
        }

        // Clean capability cache (older than 10 minutes)
        for (const [key, value] of this.capabilityCache) {
            if (now - value.timestamp > 600000) {
                this.capabilityCache.delete(key);
            }
        }

        this.credentialManager.auditLogger('SECURITY_CACHE_CLEANUP', {
            nonceCacheSize: this.nonceCache.size,
            capabilityCacheSize: this.capabilityCache.size
        });
    }

    /**
     * Get security status summary
     * @returns {Object} Security status
     */
    getSecurityStatus() {
        return {
            timestamp: new Date().toISOString(),
            caches: {
                nonces: this.nonceCache.size,
                capabilities: this.capabilityCache.size
            },
            roles: Array.from(this.roleDefinitions.keys()),
            securityFeatures: [
                'nonce_verification',
                'capability_checking',
                'role_validation',
                'query_sanitization',
                'auth_state_validation'
            ]
        };
    }
}

// Singleton instance
let wpSecurityHelpersInstance = null;

/**
 * Get singleton instance of WordPressSecurityHelpers
 * @returns {WordPressSecurityHelpers}
 */
function getWordPressSecurityHelpers() {
    if (!wpSecurityHelpersInstance) {
        wpSecurityHelpersInstance = new WordPressSecurityHelpers();
    }
    return wpSecurityHelpersInstance;
}

module.exports = {
    WordPressSecurityHelpers,
    getWordPressSecurityHelpers
};