<?php
/**
 * Cloonar TYPO3 Deployer Recipe
 * 
 * Shared deployment configuration for all TYPO3 projects.
 * 
 * Usage in project's build/deploy.php:
 *   require __DIR__ . '/../../vendor/cloonar/ci-templates/deployer/typo3-recipe.php';
 *   // Or via raw git URL during transition:
 *   // require 'https://git.cloonar.com/Cloonar/ci-templates/raw/branch/main/deployer/typo3-recipe.php';
 *   
 *   import(__DIR__ . '/servers.yaml');
 *   
 *   host('stage')->set('cachetool', '/var/run/phpfpm/PROJECT.cloonar.dev.sock');
 *   host('production')->set('cachetool', '/var/run/phpfpm/PROJECT.TLD.sock');
 */

namespace Deployer;

require 'recipe/common.php';
require 'contrib/rsync.php';
require 'contrib/cachetool.php';

// =============================================================================
// PHP Configuration
// =============================================================================

set('bin/php', function () {
    return '/run/current-system/sw/bin/php';
});

// =============================================================================
// Shared Directories & Files
// =============================================================================

set('shared_dirs', [
    'public/fileadmin',
    'var'
]);

set('shared_files', [
    '.env',
    'config/system/additional.php',
]);

set('writable_dirs', [
    'public/typo3temp'
]);

// =============================================================================
// Rsync Configuration
// =============================================================================

set('rsync_src', '../');

set('rsync', [
    'exclude' => [
        // Shared (will be symlinked)
        'public/fileadmin',
        'var',
        '.env',
        'config/system/additional.php',
        // Build & dev
        '.composer-cache',
        'build',
        '.git*',
        '.ddev',
        '.editorconfig',
        '.idea',
        'tests',
        'node_modules',
        // Config files
        '.php-cs-fixer.php',
        'phpstan.neon',
        'phpstan-baseline.neon',
        'psalm.xml',
        'psalm-baseline.xml',
        'renovate.json',
        '*.md',
    ],
    'exclude-file' => false,
    'include' => [],
    'include-file' => false,
    'filter' => ['dir-merge,-n /.gitignore'],
    'filter-file' => false,
    'filter-perdir' => false,
    'flags' => 'avz',
    'options' => ['delete'],
    'timeout' => 300
]);

// Disable git-based code update (we use rsync)
task('deploy:update_code')->hidden()->disable();

// =============================================================================
// TYPO3 Tasks
// =============================================================================

task('typo3:extension:setup', function () {
    cd('{{release_or_current_path}}');
    run('{{bin/php}} bin/typo3 extension:setup');
})->desc('Run TYPO3 extension:setup');

task('typo3:cache:flush', function () {
    cd('{{release_or_current_path}}');
    run('{{bin/php}} bin/typo3 cache:flush');
})->desc('Flush TYPO3 caches');

task('typo3:cache:warmup', function () {
    cd('{{release_or_current_path}}');
    run('{{bin/php}} bin/typo3 cache:warmup');
})->desc('Warmup TYPO3 caches');

task('typo3:language:update', function () {
    cd('{{release_or_current_path}}');
    run('{{bin/php}} bin/typo3 language:update');
})->desc('Update TYPO3 language files');

// Helper to get correct path (release during deploy, current after switch)
set('release_or_current_path', function () {
    return test('[ -d {{release_path}} ]') ? get('release_path') : 'current';
});

// =============================================================================
// PHP-FPM Reload (for NixOS infrastructure)
// =============================================================================

task('php:reload', function () {
    run('php-reload');
})->desc('Reload PHP-FPM');

// =============================================================================
// Deployment Strategies
// =============================================================================

/**
 * release:create - Upload new release without switching
 * Use for staged deployments where you want to test before switching
 */
task('release:create', [
    'deploy:prepare',
    'rsync',
    'deploy:vendors',
    'deploy:shared',
    'deploy:writable',
    'typo3:extension:setup',
    'deploy:unlock',
    'deploy:success'
])->desc('Create new release (upload only, no switch)');

/**
 * release:switch - Switch to latest release and cleanup
 * Run after release:create once testing passes
 */
task('release:switch', [
    'deploy:symlink',
    'cachetool:clear:opcache',
    'php:reload',
    'typo3:cache:flush',
    'typo3:extension:setup',
    'typo3:language:update',
    'typo3:cache:warmup',
    'deploy:unlock',
    'deploy:cleanup',
    'deploy:success'
])->desc('Switch to latest release');

/**
 * deploy - Full deployment (create + switch in one go)
 * Use for simple deployments without staged testing
 */
task('deploy', [
    'deploy:prepare',
    'rsync',
    'deploy:vendors',
    'deploy:shared',
    'deploy:writable',
    'typo3:extension:setup',
    'deploy:symlink',
    'cachetool:clear:opcache',
    'php:reload',
    'typo3:cache:flush',
    'typo3:language:update',
    'typo3:cache:warmup',
    'deploy:unlock',
    'deploy:cleanup',
    'deploy:success'
])->desc('Full deployment (create + switch)');

// =============================================================================
// Hooks
// =============================================================================

// Unlock on failure
after('deploy:failed', 'deploy:unlock');
