<?php

class password_manager {
    
    // Password strength levels
    const STRENGTH_VERY_WEAK = 1;
    const STRENGTH_WEAK = 2;
    const STRENGTH_FAIR = 3;
    const STRENGTH_GOOD = 4;
    const STRENGTH_STRONG = 5;
    
    // Common words to avoid in passwords
    private $common_words = array(
        'password', '123456', 'qwerty', 'admin', 'user', 'login', 'welcome',
        'letmein', 'monkey', 'dragon', 'master', 'hello', 'freedom', 'whatever',
        'qazwsx', 'trustno1', 'jordan', 'harley', 'ranger', 'iwantu', 'jennifer',
        'hunter', 'buster', 'soccer', 'baseball', 'football', 'shadow', 'mike',
        'mustang', 'summer', 'love', 'ashley', 'nicole', 'chelsea', 'biteme',
        'matthew', 'access', 'yankees', '987654321', 'dallas', 'austin', 'thunder',
        'taylor', 'matrix', 'mobilephone', 'michael', 'jessica', 'jordan23',
        'superman', 'hello123', 'charlie', 'andrew', 'michelle', 'love123',
        'sunshine', 'robert', 'daniel', 'basketball', 'buster', 'george',
        'computer', 'michelle', 'jessica', 'pepper', '1111', 'zxcvbnm', '555555'
    );
    
    // Word lists for password generation
    private $adjectives = array(
        'brave', 'clever', 'swift', 'bright', 'calm', 'eager', 'gentle', 'happy',
        'kind', 'lively', 'mighty', 'noble', 'proud', 'quick', 'radiant', 'smart',
        'tender', 'wise', 'zealous', 'active', 'bold', 'cheerful', 'daring',
        'energetic', 'friendly', 'graceful', 'honest', 'intelligent', 'joyful',
        'loyal', 'magical', 'peaceful', 'reliable', 'strong', 'trustworthy'
    );
    
    private $nouns = array(
        'dragon', 'phoenix', 'tiger', 'eagle', 'wolf', 'bear', 'lion', 'hawk',
        'dolphin', 'panther', 'falcon', 'shark', 'jaguar', 'leopard', 'cheetah',
        'butterfly', 'rainbow', 'mountain', 'ocean', 'forest', 'river', 'star',
        'moon', 'sun', 'cloud', 'thunder', 'lightning', 'storm', 'breeze',
        'crystal', 'diamond', 'emerald', 'ruby', 'sapphire', 'gold', 'silver'
    );
    
    private $symbols = array('!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '_', '+', '=', '{', '}', '[', ']', '|', '\\', ':', ';', '"', "'", '<', '>', ',', '.', '?', '/');
    private $numbers = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
    
    /**
     * Check password strength
     */
    public function check_password_strength($password) {
        $score = 0;
        $feedback = array();
        
        // Length check
        if (strlen($password) >= 12) {
            $score += 2;
        } elseif (strlen($password) >= 8) {
            $score += 1;
        } else {
            $feedback[] = 'Password should be at least 8 characters long';
        }
        
        // Character variety checks
        if (preg_match('/[a-z]/', $password)) $score += 1;
        if (preg_match('/[A-Z]/', $password)) $score += 1;
        if (preg_match('/[0-9]/', $password)) $score += 1;
        if (preg_match('/[^a-zA-Z0-9]/', $password)) $score += 1;
        
        // Check for common patterns
        if (preg_match('/(.)\1{2,}/', $password)) {
            $score -= 1;
            $feedback[] = 'Avoid repeated characters';
        }
        
        if (preg_match('/(123|abc|qwe|asd|zxc)/i', $password)) {
            $score -= 1;
            $feedback[] = 'Avoid common sequences';
        }
        
        // Check for common words
        $password_lower = strtolower($password);
        foreach ($this->common_words as $word) {
            if (strpos($password_lower, $word) !== false) {
                $score -= 2;
                $feedback[] = 'Avoid common words';
                break;
            }
        }
        
        // Entropy calculation (simplified)
        $unique_chars = count(array_unique(str_split($password)));
        if ($unique_chars >= 8) $score += 1;
        
        // Normalize score
        $score = max(1, min(5, $score));
        
        return array(
            'score' => $score,
            'strength' => $this->get_strength_label($score),
            'feedback' => $feedback,
            'color' => $this->get_strength_color($score)
        );
    }
    
    /**
     * Get strength label
     */
    private function get_strength_label($score) {
        switch ($score) {
            case 1: return 'Very Weak';
            case 2: return 'Weak';
            case 3: return 'Fair';
            case 4: return 'Good';
            case 5: return 'Strong';
            default: return 'Unknown';
        }
    }
    
    /**
     * Get strength color
     */
    private function get_strength_color($score) {
        switch ($score) {
            case 1: return '#d9534f'; // Red
            case 2: return '#f0ad4e'; // Orange
            case 3: return '#ffc107'; // Yellow
            case 4: return '#5bc0de'; // Blue
            case 5: return '#5cb85c'; // Green
            default: return '#999';
        }
    }
    
    /**
     * Generate a secure password
     */
    public function generate_password($length = 16) {
        // Create a word-based password with proper structure
        $adjective = $this->adjectives[array_rand($this->adjectives)];
        $noun = $this->nouns[array_rand($this->nouns)];
        $symbol = $this->symbols[array_rand($this->symbols)];
        $number = $this->numbers[array_rand($this->numbers)];
        
        // Capitalize the adjective and noun for better readability
        $adjective = ucfirst($adjective);
        $noun = ucfirst($noun);
        
        // Create the base password: Adjective + Noun + Symbol + Number
        $password = $adjective . $noun . $symbol . $number;
        
        // If we need more length, add additional random characters
        if (strlen($password) < $length) {
            $remaining_length = $length - strlen($password);
            $all_chars = array_merge(
                range('a', 'z'),
                range('A', 'Z'),
                $this->numbers,
                $this->symbols
            );
            
            for ($i = 0; $i < $remaining_length; $i++) {
                $password .= $all_chars[array_rand($all_chars)];
            }
        }
        
        // If password is too long, truncate it
        if (strlen($password) > $length) {
            $password = substr($password, 0, $length);
        }
        
        return $password;
    }
    
    /**
     * Validate password change
     */
    public function validate_password_change($current_password, $new_password, $confirm_password, $username) {
        $errors = array();
        
        // Check if current password is correct
        $error = '';
        if (!pam_auth($username, $current_password, $error)) {
            $errors[] = 'Current password is incorrect';
        }
        
        // Check if new passwords match
        if ($new_password !== $confirm_password) {
            $errors[] = 'New passwords do not match';
        }
        
        // Check if new password is different from current
        if ($current_password === $new_password) {
            $errors[] = 'New password must be different from current password';
        }
        
        // Check password strength
        $strength = $this->check_password_strength($new_password);
        if ($strength['score'] < 3) {
            $errors[] = 'Password is too weak. ' . implode(', ', $strength['feedback']);
        }
        
        return array(
            'valid' => empty($errors),
            'errors' => $errors,
            'strength' => $strength
        );
    }
    
    /**
     * Change user password
     */
    public function change_password($username, $new_password) {
        // Use chpasswd command to change password
        $command = "echo '$username:$new_password' | chpasswd";
        $result = shell_exec($command);
        
        return empty($result); // chpasswd returns empty string on success
    }
    
    /**
     * Get password requirements
     */
    public function get_password_requirements() {
        return array(
            'min_length' => 8,
            'recommended_length' => 12,
            'require_uppercase' => true,
            'require_lowercase' => true,
            'require_numbers' => true,
            'require_symbols' => true,
            'avoid_common_words' => true,
            'avoid_sequences' => true
        );
    }
} 