<?php declare(strict_types=1);
/**
 * @author Ryan Spaeth <rspaeth@spaethtech.com>
 * @copyright 2025 - Spaeth Technologies, Archous Networks
 */

namespace SpaethTech\UCRM\SDK\Composer;

use Composer\Script\Event;

if (!defined("PLUGIN_DIR"))
    define("PLUGIN_DIR", realpath(__DIR__."/../../"));

if (!defined("PLUGIN_TMP"))
    define("PLUGIN_TMP", PLUGIN_DIR . "/tmp");

class Scripts
{
    public static function getTempFolder(): string|false
    {
        if (!is_dir(PLUGIN_TMP))
            mkdir(PLUGIN_TMP);

        return realpath(PLUGIN_TMP);
    }


    public static function validate(Event $event): void
    {
        // TODO: Validation?
    }

    public static function backup(Event $event): void
    {
        $owd = getcwd();
        chdir(PLUGIN_DIR);

        echo "Creating backup...\n";
        exec("mkdir -p tmp && rm -rf tmp/*");
        exec("cp -r vendor tmp/");

        chdir($owd);
    }

    public static function optimize(Event $event): void
    {
        $owd = getcwd();
        chdir(PLUGIN_DIR);

        echo "Optimizing dependencies...\n";
        exec("composer --ansi update --no-dev --optimize-autoloader");

        chdir($owd);
    }

    public static function restore(Event $event): void
    {
        $owd = getcwd();
        chdir(PLUGIN_DIR);

        if (!is_dir("tmp"))
        {
            echo "No backup found, skipping restore...\n";
            return;
        }

        echo "Restoring backup...\n";
        exec("rm -rf vendor");
        exec("mv tmp/vendor .");

        exec("rm -rf tmp");

        chdir($owd);
    }

    public static function increment(Event $event): void
    {
        $composerFile = PLUGIN_DIR . "/composer.json";
        $composerText = file_get_contents($composerFile);
        $composerJson = json_decode($composerText, true);

        $manifestFile = PLUGIN_DIR . "/manifest.json";
        $manifestText = file_get_contents($manifestFile);
        $manifestJson = json_decode($manifestText, true);

        $version = $composerJson["version"] ?? "0.0.0";

        $pattern = '/^([\d]+)\.([\d]+)\.([\d]+)(?:-(.+))?$/';
        if (!preg_match($pattern, $version, $matches))
            throw new \Exception("Invalid version format: $version");

        $major = $matches[1];
        $minor = $matches[2];
        $patch = $matches[3];
        $patch++;
        $build = $matches[4] ?? null;

        $new_version = "$major.$minor.$patch".($build ? "-$build" : "");

        $composerJson["version"] = $new_version;
        //exec("cp $composerFile ".self::getTempFolder()."/");
        file_put_contents($composerFile, json_encode($composerJson,
            JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));

        $manifestJson["information"]["version"] = $new_version;
        //exec("cp $manifestFile ".self::getTempFolder()."/");
        file_put_contents($manifestFile, json_encode($manifestJson,
            JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
    }

    public static function latest(Event $event): void
    {
        $composerFile = PLUGIN_DIR . "/composer.json";
        $composerText = file_get_contents($composerFile);
        $composerJson = json_decode($composerText, true);

        $owd = getcwd();
        chdir(PLUGIN_DIR);

        $path = $composerJson["config"]["archive-dir"] ?? "zip";
        chdir($path);

        exec("echo {$composerJson["version"]} > latest");

        chdir($owd);
    }


    public static function cleanup(Event $event): void
    {
        $composerFile = PLUGIN_DIR . "/composer.json";
        $composerText = file_get_contents($composerFile);
        $composerJson = json_decode($composerText, true);

        $path = $composerJson["config"]["archive-dir"] ?? "zip";
        $keep = $composerJson["archive"]["keep"] ?? 3;

        $owd = getcwd();
        chdir(PLUGIN_DIR);
        chdir($path);

        $files = glob("*.zip");
        usort($files, function($a, $b)
        {
            return -version_compare(
                str_replace(["provisioner-", ".zip"], "", basename($a)),
                str_replace(["provisioner-", ".zip"], "", basename($b))
            );
        });

        $removes = array_slice($files, $keep);

        foreach ($removes as $file)
            unlink($file);

        chdir($owd);
    }

    public static function relink(Event $event): void
    {
        // Not using Symlinks in this project!
    }

    public static function unlink(Event $event): void
    {
        // Not using Symlinks in this project!
    }
}
