<?php

declare(strict_types=1);

namespace Tricks\Static;

use Composer\Script\Event;
use z4kn4fein\SemVer\SemverException;
use z4kn4fein\SemVer\Version;

final class Release
{
    public static function release(Event $event): void
    {
        if (trim(`git diff --quiet || echo 'dirty'` ?? '') === 'dirty') {
            exit('You have unstaged changes. Please commit or stash them.'.PHP_EOL);
        }
        if (trim(`git diff --cached --quiet || echo 'cached'` ?? '') === 'cached') {
            exit('You have staged changes. Please commit or stash them.'.PHP_EOL);
        }
        $latestTag = self::trimmedResponse('git describe --tags --abbrev=0');
        $currentHash = self::trimmedResponse('git show-ref --head | head -n 1');
        $latestTagHash = self::trimmedResponse("git show-ref -s $latestTag");

        if ($currentHash === $latestTagHash) {
            exit('This commit already has a tag.'.PHP_EOL);
        }
        try {
            $version = Version::parse($latestTag);
            $newVersion = match ($event->getArguments()[0]) {
                'patch' => $version->getNextPatchVersion(),
                'minor' => $version->getNextMinorVersion(),
                'major' => $version->getNextMajorVersion(),
                default => exit('Please specify patch, minor or major as parameter.'.PHP_EOL),
            };
        } catch (SemverException $e) {
            exit($e->getMessage());
        }

        echo "Going from $version to $newVersion".PHP_EOL;
        shell_exec("git tag $newVersion");
        shell_exec("git push origin main $newVersion");
    }

    private static function trimmedResponse(string $command): string
    {
        $return = shell_exec($command);
        if (! is_string($return)) {
            exit("ERROR: Command response is not of type string: `$command` `$return`");
        }

        return trim($return);
    }
}
