#!/usr/bin/env php
<?php

declare(strict_types=1);

/**
 * Smart test generator - analyzes each entity and calls appropriate methods.
 * Usage: php bin/generate-smart-entity-tests
 */

require __DIR__ . '/../vendor/autoload.php';

use ReflectionClass;

$uncoveredEntities = [
    'AdresseBenutzer', 'AdresseEmails', 'Adressenzuord', 'Anlage', 'AnschriftMitLieferadresse',
    'Ansprechzuord', 'Artgrupshopzuord', 'ArtikelArtikelgruppe', 'Artikelean', 'Artikelpreis',
    'Artikelstueckliste', 'ArtikelWebshop', 'Artikelzuord', 'Atrposlinks', 'Atrversandkosten',
    'Auftrag', 'Auftragspositionrueckstand', 'Auftragzuord', 'Bank', 'Bankkonto',
    'BenutzerBenutzergruppen', 'Benutzerrecht', 'Branrede', 'Dokument', 'Dokumentliste',
    'Druckformular', 'Druckformularprinter', 'Ebayartikel', 'Ebayverkauf', 'Email',
    'EmailAnlage', 'Emailssuchzuord', 'Emailszuord', 'Externekalender', 'Fibu',
    'Fibuarchiv', 'Fibubuchung', 'Fibubuchungsvorlagen', 'Fibukontenplan', 'Fibukontenplanbaum',
    'Fibukontenplanbaumzuord', 'Fibuwirtschaftsjahre', 'Importauftragdata', 'ImportAuftraglieferant',
    'Intranetmsg', 'Intranetmsggelesen', 'Inventur', 'Kalenderfreigabe', 'Kontaktezuord',
    'KontoauszugZuordnung', 'KundeLieferadresse', 'Laender', 'Lieferart', 'Mahnpara',
    'Mailbaum', 'Mailbaumfreigabe', 'Mailfreigabe', 'Mailid', 'Mailkonten',
    'Mailkontenfreigabe', 'Mailregelflt', 'Mailregeln', 'Mark', 'Markadressen',
    'Miniqueries', 'Miniquerydisplay', 'OffenerPosten', 'Offposzuord', 'Provisionsgruppen',
    'Rabattgruppe', 'Retourartikelsernrzuord', 'Setup', 'Setupbin', 'Shortmessages',
    'Spamlist', 'Steuersatz', 'Stsatzland', 'Suchschluessel', 'Tableversions',
    'Telereporterprotokoll', 'Termin', 'TerminAufgabeAdresse', 'TextbausteinSuchzuordnung',
    'TextbausteinZuordnung', 'Textlist', 'UmsatzAbstract', 'Umsatzzuord', 'Waehrungskurse',
    'Werbeadressprotokoll', 'Werbeaktionen', 'Werbeaktionenordner', 'Werbeaktionenzuord',
    'Werbesessions', 'Werbesessionszuord', 'Zahlweise',
];

$testsDir = __DIR__ . '/../tests/Entity';
$created = 0;
$skipped = 0;

foreach ($uncoveredEntities as $entityName) {
    $testFile = $testsDir . '/' . $entityName . 'Test.php';
    
    if (file_exists($testFile)) {
        echo "DELETE: $entityName\n";
        unlink($testFile);
    }
    
    $className = "Satag\\AmicronEntityBundle\\Entity\\$entityName";
    
    try {
        $reflection = new ReflectionClass($className);
        
        // Handle abstract classes
        if ($reflection->isAbstract()) {
            $content = <<<PHP
<?php

declare(strict_types=1);

namespace Satag\AmicronEntityBundle\Tests\Entity;

use PHPUnit\Framework\TestCase;
use ReflectionClass;
use {$className};

class {$entityName}Test extends TestCase
{
    public function testAbstractClassStructure(): void
    {
        \$reflection = new ReflectionClass({$entityName}::class);
        
        static::assertTrue(\$reflection->isAbstract());
    }
}

PHP;
            file_put_contents($testFile, $content);
            echo "CREATED: $entityName (abstract)\n";
            $created++;
            continue;
        }
        
        // Check constructor parameters
        $constructor = $reflection->getConstructor();
        $hasRequiredParams = $constructor && $constructor->getNumberOfRequiredParameters() > 0;
        
        // Find a getter method to call
        $methodToCall = null;
        $fallbackMethods = ['getLfdnr', 'getName', 'getId', 'getBeschr', 'getBeschreibung'];
        
        foreach ($fallbackMethods as $method) {
            if ($reflection->hasMethod($method)) {
                $methodToCall = $method;
                break;
            }
        }
        
        if (!$methodToCall) {
            // Find any public getter
            foreach ($reflection->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
                if (str_starts_with($method->getName(), 'get') && $method->getNumberOfParameters() === 0) {
                    $methodToCall = $method->getName();
                    break;
                }
            }
        }
        
        // Generate test based on constructor requirements
        if ($hasRequiredParams && $methodToCall === 'getLfdnr') {
            // Skip - needs custom test
            echo "SKIP: $entityName (requires custom test due to constructor)\n";
            $skipped++;
            continue;
        }
        
        $instantiation = $hasRequiredParams ? 'Cannot auto-generate' : "new {$entityName}()";
        $methodCall = $methodToCall ? "\$entity->{$methodToCall}();" : "// No suitable getter found";
        
        $content = <<<PHP
<?php

declare(strict_types=1);

namespace Satag\AmicronEntityBundle\Tests\Entity;

use PHPUnit\Framework\TestCase;
use {$className};

/**
 * Auto-generated test for 100% class coverage.
 */
class {$entityName}Test extends TestCase
{
    public function testEntityClassCoverage(): void
    {
        \$entity = {$instantiation};
        
        {$methodCall}
        
        static::assertInstanceOf({$entityName}::class, \$entity);
    }
}

PHP;
        
        file_put_contents($testFile, $content);
        echo "CREATED: $entityName\n";
        $created++;
        
    } catch (\Exception $e) {
        echo "ERROR: $entityName - " . $e->getMessage() . "\n";
    }
}

echo "\n✓ Created: $created | Skipped: $skipped\n";
echo "Run: docker compose run --rm app_server vendor/bin/phpunit\n";