#!/usr/bin/env php
<?php
use Amp\Promise;
use CatPaw\Environment\Attributes\Environment;

use function Amp\File\createDirectoryRecursively;
use function Amp\File\deleteFile;
use function Amp\File\exists;
use function Amp\File\write;
use function CatPaw\deleteDirectoryRecursively;

/**
  * 
  * @param string $name 
  * @param string $entry 
  * @param string $libraries 
  * @param null|array $ignore 
  * @return Generator<int, Promise<bool>|Promise<void>|Promise<string[]>, mixed, void> 
  * @throws Error 
  */
#[Environment("build.yml")]
function main(){

    /**
     * @var string $name
     * @var string $entry
     * @var string $libraries
     * @var string $match
     */

    $name = $_ENV['name']??'';
    $entry = $_ENV['entry']??'';
    $libraries = $_ENV['libraries']??'';
    $match = $_ENV['match']??'';

    $name = str_replace(['"',"\n"], ['\\"',''], $name);
    $entry = str_replace(['"',"\n"], ['\\"',''], $entry);
    $libraries = str_replace(['"',"\n"], ['\\"',''], $libraries);
    
    $isWindows = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';

    if (!str_starts_with($entry, './')) {
        if(!$isWindows) {
            die("The entry file path must be relative to the project, received: $entry.".PHP_EOL);
        }
        if (!str_starts_with($entry, '.\\')) {
            die("The entry file path must be relative to the project, received: $entry.".PHP_EOL);
        }
    }
    
    foreach (!$libraries?[]:\preg_split('/,|;/', $libraries) as $libraries) {
        if (!str_starts_with($libraries, './')) {
            if(!$isWindows) {
                die("All library directory paths must be relative to the project, received: $libraries.".PHP_EOL);
            }
            if (str_starts_with($libraries, '.\\')) {
                continue;
            }
        }
    }

    $app = 'dist/app.phar';
    $start = 'dist/start';

    $dirnameStart = dirname($start);
    try {

        if(yield exists($dirnameStart)){
            yield deleteDirectoryRecursively($dirnameStart);
        }

        yield createDirectoryRecursively($dirnameStart);

        yield write($start,<<<PHP
        <?php
        use Amp\File\Filesystem;
        use Amp\Loop;
        use CatPaw\Amp\File\CatPawDriver;
        use CatPaw\Bootstrap;
        \$_ENV = [
            ...\$_ENV,
            ...getenv(),
        ];
        require 'vendor/autoload.php';

        if (isset(\$_ENV["CATPAW_FILE_DRIVER"]) && \$_ENV["CATPAW_FILE_DRIVER"]) {
            Loop::setState(\Amp\File\Driver::class, new Filesystem(new CatPawDriver));
        }
        Bootstrap::start(
            entry: "$entry",
            name: "$name",
            libraries: "$libraries",
            info: false,
            dieOnChange: false,
            resources: '',
        );
        PHP);

        if (yield exists($app)) {
            yield deleteFile($app);
        }

        if (yield exists($app . '.gz')) {
            yield deleteFile($app . '.gz');
        }
        
        $phar = new Phar($app);

        $phar->startBuffering();

        $phar->buildFromDirectory('.',$match);

        $phar->setStub(
            "#!/usr/bin/env php \n".$phar->createDefaultStub($start)
        );

        $phar->stopBuffering();

        $phar->compressFiles(Phar::GZ);

        # Make the file executable
        chmod($app, 0770);

        yield deleteFile($start);

        echo "$app successfully created" . PHP_EOL;
    } catch (Exception $e) {
        die(((string)$e).PHP_EOL);
    }
}