<?php
/**
 * Base Setup Command Class
 *
 * @todo        Nach Foundation/Console verlagern.
 *
 * @version     1.0.$Revision:$
 * @version     SVN: $Id:$
 * @package     bplan-base/globals
 * @subpackage  Commands
 * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
 * @copyright   Copyright (C) 2025, 2026 bplan-solutions GmbH & Co. KG <https://www.bplan-solutions.de/>
 * /Δ\
 */

namespace BplanBase\Globals\Console;


use BplanBase\Globals\Console\Output;
use BplanBase\Globals\Console\Prompt;
use BplanBase\Globals\Setup\FilePublisher;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;
use Symfony\Component\Process\Process;


use function Laravel\Prompts\clear;


/**
 * Base Setup Command Class
 *
 * @version     1.2.0 / 2026-05-15
 * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
 */
abstract class BaseSetup extends Command
{


/* +++ TRAITS +++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */


/* +++ CLASS CONSTANTS +++ ++++++++++++++++++++++++++++++++++++++++++++++++++ */


/* +++ OBJECT MEMBERS +++ +++++++++++++++++++++++++++++++++++++++++++++++++++ */


    /**
     * @var     string
     */
    protected string $_basePath;


    /**
     * @var     boolean
     */
    protected bool $_firstRun;


    /**
     * @var     Output
     */
    protected Output $_Output;


    /**
     * @var     Prompt
     */
    protected Prompt $_Prompt;


    /**
     * @var     array
     */
    protected array $_publishFiles = [];


    /**
     * @var     array<string, string>
     */
    protected array $_publishReplacements = [];


/* +++ CLASS MEMBERS +++ ++++++++++++++++++++++++++++++++++++++++++++++++++++ */


    /**
     * @var     int $_commandTimeout
     */
    protected static int $_commandTimeout = 300;


/* +++ OBJECT METHODS +++ +++++++++++++++++++++++++++++++++++++++++++++++++++ */


    /**
     *
     * @return 	    void
     *
     * @version     1.0.0 / 2026-02-25
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    protected function _init(): void
    {
        $this->_Output = new Output($this);
        $this->_Prompt = new Prompt($this);

        Output::registerStatusColor(FilePublisher::STATUS_DONE, 'green');
        Output::registerStatusColor(FilePublisher::STATUS_MISSING, 'red');
        Output::registerStatusColor(FilePublisher::STATUS_SKIPPED, 'gray');

    } // _init()


    /**
     *
     * @return 	    void
     *
     * @version     1.1.0 / 2026-05-15
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    protected function _publishFiles(): void
    {
        if (empty($this->_publishFiles)) {
            return;
        }
        $this->_Output->caption('Publish files');

        if (!empty($this->_publishFiles['always'])) {
            $Publisher = new FilePublisher($this->_basePath, $this->_publishFiles['always'], [$this, 'publishMessage']);

            $Publisher->force()->withReplacements($this->_publishReplacements)->publish();
        }
        if (!empty($this->_publishFiles['once'])) {
            $Publisher = new FilePublisher($this->_basePath, $this->_publishFiles['once'], [$this, 'publishMessage']);

            if ($this->_firstRun === true) {
                $Publisher->force();
            }
            $Publisher->withReplacements($this->_publishReplacements)->publish();
        }
    } // _publishFiles()


    /**
     *
     * @param       array $command
     
     * @param       bool  $showOutput
     *              Print stdout even on success.
     *
     * @return      void
     *
     * @version     2.0.0 / 2026-04-19
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    protected function _runShellCommand(array $command, bool $showOutput = false): void
    {
        $Process = new Process($command);

        $Process->setTimeout(self::$_commandTimeout);

        $Process->run();

        if (!$Process->isSuccessful()) {
            $this->_Output->error('  Command failed: '.implode(' ', $command));

            $stdout = trim($Process->getOutput());
            $stderr = trim($Process->getErrorOutput());

            if ($stdout !== '') {
                $this->_Output->error($stdout);
            }
            if ($stderr !== '') {
                $this->_Output->error($stderr);
            }
        } elseif ($showOutput === true) {
            $output = trim($Process->getOutput());

            if ($output !== '') {
                $this->_Output->print($output);
            }
        }
    } // _runShellCommand()


    /**
     *
     * @param       array $event
     *
     * @return      void
     *
     * @version     1.0.0 / 2026-02-25
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    public function publishMessage(array $event)
    {
        $msg  = $event['message'];
        $source  = $event['source'];
        $status = $event['status'];
        $target  = $event['target'];

        $message = 'Publish '.$target;

        $this->_Output->statusMessage($message, $status);

    } // publishMessage()


/* +++ CLASS METHODS +++ ++++++++++++++++++++++++++++++++++++++++++++++++++++ */


} // abstract class BaseSetup extends Command {}
