#!/usr/bin/env php
<?php
/**
 * Check for duplicate class declarations in WordPress plugin
 * Detects duplicate classes, interfaces, traits, functions, and constants
 */

$plugin_dir = $argv[1] ?? __DIR__;

echo "=== Checking for Duplicates ===\n\n";

function scan_directory($dir, $extensions = ['php']) {
    $files = [];
    $iterator = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS)
    );
    
    foreach ($iterator as $file) {
        if (in_array(strtolower($file->getExtension()), $extensions)) {
            $files[] = $file->getPathname();
        }
    }
    
    return $files;
}

function extract_declarations($content) {
    $declarations = [];
    
    // Extract classes
    if (preg_match_all('/^\s*(?:abstract\s+)?class\s+(\w+)/m', $content, $matches)) {
        foreach ($matches[1] as $class) {
            $declarations['classes'][$class][] = 'class';
        }
    }
    
    // Extract interfaces
    if (preg_match_all('/^\s*interface\s+(\w+)/m', $content, $matches)) {
        foreach ($matches[1] as $interface) {
            $declarations['interfaces'][$interface][] = 'interface';
        }
    }
    
    // Extract traits
    if (preg_match_all('/^\s*trait\s+(\w+)/m', $content, $matches)) {
        foreach ($matches[1] as $trait) {
            $declarations['traits'][$trait][] = 'trait';
        }
    }
    
    // Extract functions (non-namespaced)
    if (preg_match_all('/^\s*function\s+(\w+)/m', $content, $matches)) {
        foreach ($matches[1] as $function) {
            if (!isset($declarations['functions'][$function])) {
                $declarations['functions'][$function] = [];
            }
        }
    }
    
    return $declarations;
}

function check_duplicate_classes($files) {
    $all_classes = [];
    $duplicates = [];
    
    foreach ($files as $file) {
        $content = file_get_contents($file);
        
        // Check for classes
        if (preg_match_all('/^\s*(?:abstract\s+)?class\s+(\w+)/m', $content, $matches)) {
            foreach ($matches[1] as $class) {
                if (!isset($all_classes[$class])) {
                    $all_classes[$class] = [];
                }
                $all_classes[$class][] = $file;
            }
        }
        
        // Check for interfaces
        if (preg_match_all('/^\s*interface\s+(\w+)/m', $content, $matches)) {
            foreach ($matches[1] as $interface) {
                $key = strtolower($interface);
                if (!isset($all_classes[$key])) {
                    $all_classes[$key] = [];
                }
                $all_classes[$key][] = $file;
            }
        }
    }
    
    foreach ($all_classes as $name => $files_list) {
        if (count($files_list) > 1) {
            $duplicates['classes'][$name] = $files_list;
        }
    }
    
    return $duplicates;
}

function check_duplicate_functions($files) {
    $all_functions = [];
    $duplicates = [];
    
    foreach ($files as $file) {
        $content = file_get_contents($file);
        
        // Skip content inside classes, interfaces, and traits
        $content = preg_replace('/class\s+\w+\s*\{[^}]*\}/s', '', $content);
        $content = preg_replace('/interface\s+\w+\s*\{[^}]*\}/s', '', $content);
        $content = preg_replace('/trait\s+\w+\s*\{[^}]*\}/s', '', $content);
        
        if (preg_match_all('/^\s*function\s+(\w+)\s*\(/m', $content, $matches)) {
            foreach ($matches[1] as $function) {
                if (!isset($all_functions[$function])) {
                    $all_functions[$function] = [];
                }
                $all_functions[$function][] = $file;
            }
        }
    }
    
    foreach ($all_functions as $name => $files_list) {
        if (count($files_list) > 1) {
            $duplicates['functions'][$name] = $files_list;
        }
    }
    
    return $duplicates;
}

echo "Scanning directory: $plugin_dir\n";
$files = scan_directory($plugin_dir);
echo "Found " . count($files) . " PHP files\n\n";

$class_duplicates = check_duplicate_classes($files);
$function_duplicates = check_duplicate_functions($files);

$has_issues = false;

if (!empty($class_duplicates['classes'])) {
    $has_issues = true;
    echo "❌ Duplicate class/interface declarations found:\n";
    foreach ($class_duplicates['classes'] as $name => $files_list) {
        echo "   - $name found in:\n";
        foreach ($files_list as $file) {
            echo "     $file\n";
        }
    }
    echo "\n";
}

if (!empty($function_duplicates['functions'])) {
    $has_issues = true;
    echo "⚠️  Potential duplicate function declarations:\n";
    foreach ($function_duplicates['functions'] as $name => $files_list) {
        echo "   - $name() found in:\n";
        foreach ($files_list as $file) {
            echo "     $file\n";
        }
    }
    echo "\n";
}

if (!$has_issues) {
    echo "✅ No duplicate declarations found\n";
} else {
    echo "⚠️  Please review the duplicates above and fix them.\n";
    echo "   Solutions:\n";
    echo "   - Use class_exists() guards around class definitions\n";
    echo "   - Consolidate duplicate declarations into one file\n";
    echo "   - Namespace conflicting classes differently\n";
}

echo "\n=== Check Complete ===\n";
exit($has_issues ? 1 : 0);
