<?php

namespace PortalPeople\NgaugeBackupSql;

use Yii;
use yii\base\BootstrapInterface;
use yii\console\Application as ConsoleApp;

/**
 * NgaugeBackupSql Module
 * 
 * Database table backup and restore module with compression and versioning.
 * 
 * @property string $backupPath Path to backup storage directory
 * @property int $retentionDays Number of days to retain backups
 * @property bool $compressBackups Whether to compress backups with gzip
 * @property array $excludeTables Tables to exclude from backup listings
 * @property string $dbComponent Name of the database component to use
 */
class Module extends \yii\base\Module implements BootstrapInterface
{
    /**
     * @var string Namespace for controllers
     */
    public $controllerNamespace = 'PortalPeople\NgaugeBackupSql\controllers';
    
    /**
     * @var string Path to backup storage directory (Yii alias or absolute path)
     */
    public $backupPath = '@backups/sql';
    
    /**
     * @var int Number of days to retain backups (0 = keep forever)
     */
    public $retentionDays = 30;
    
    /**
     * @var bool Whether to compress backups with gzip
     */
    public $compressBackups = true;
    
    /**
     * @var array Tables to exclude from backup listings
     */
    public $excludeTables = ['log', 'queue', 'session'];
    
    /**
     * @var string Name of the database component to use
     */
    public $dbComponent = 'db';
    
    /**
     * @var int Maximum file size in bytes for single backup (0 = unlimited)
     */
    public $maxBackupSize = 0;
    
    /**
     * @var string|null Path to mysqldump/mariadb-dump binary (null = auto-detect)
     */
    public $mysqldumpPath = null;
    
    /**
     * @var string|null Path to mysql/mariadb binary (null = auto-detect)
     */
    public $mysqlPath = null;

    /**
     * @inheritdoc
     */
    public function init()
    {
        parent::init();
        
        // Set default module ID if not set
        if ($this->id === null) {
            $this->id = 'db-backup';
        }
        
        // Ensure backup directory exists
        $backupPath = Yii::getAlias($this->backupPath);
        if (!is_dir($backupPath)) {
            @mkdir($backupPath, 0755, true);
        }
        
    }

    /**
     * Bootstrap method to be called during application bootstrap stage
     * 
     * @param \yii\base\Application $app The application instance
     */
    public function bootstrap($app)
    {
        // Register module if not already registered
        if (!isset($app->getModules()[$this->id])) {
            $app->setModule($this->id, [
                'class' => 'PortalPeople\NgaugeBackupSql\Module',
                'backupPath' => $this->backupPath,
                'retentionDays' => $this->retentionDays,
                'compressBackups' => $this->compressBackups,
                'excludeTables' => $this->excludeTables,
                'dbComponent' => $this->dbComponent,
                'maxBackupSize' => $this->maxBackupSize,
                'mysqldumpPath' => $this->mysqldumpPath,
                'mysqlPath' => $this->mysqlPath,
            ]);
        }
        
        // Register console command for console applications
        if ($app instanceof ConsoleApp) {
            $app->controllerMap['db-backup'] = [
                'class' => 'PortalPeople\NgaugeBackupSql\BackupCommand',
                'module' => $app->getModule($this->id),
            ];
        }
        
        // Register Backup component alias
        Yii::$container->set('PortalPeople\NgaugeBackupSql\components\BackupManager', [
            'module' => $app->getModule($this->id),
        ]);

        \yii\base\Event::on(\backend\controllers\ProductsController::class, 'beforePricingImportApply', function ($event) {
           $file = \PortalPeople\NgaugeBackupSql\components\Backup::SQLTable('pricing', 'pricing_'.date('Ymd_Hi').'.sql.gz');
           Yii::warning("Created backup of 'Pricing' table before import: " . $file);
        });
    }
    
    /**
     * Get the resolved backup path
     * 
     * @return string Absolute path to backup directory
     */
    public function getBackupPath()
    {
        return Yii::getAlias($this->backupPath);
    }
    
    /**
     * Get the database component
     * 
     * @return \yii\db\Connection
     */
    public function getDb()
    {
        return Yii::$app->get($this->dbComponent);
    }
}
