<?php

namespace App\Service;

use App\Message\UpdateKeylighterMessage;
use Kadet\Highlighter\KeyLighter;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Messenger\MessageBusInterface;

class KeyLighterVersioner
{
    const URL = 'https://packagist.org/p/kadet/keylighter.json';

    private $current;

    private $filesystem;
    private $parameters;
    private $bus;

    public function __construct(Filesystem $filesystem, ParameterBagInterface $parameters, MessageBusInterface $bus)
    {
        $this->filesystem = $filesystem;
        $this->parameters = $parameters;
        $this->bus        = $bus;
    }

    public function getAvailableVersions()
    {
        $info = $this->getInstalledInfo();

        return array_keys($info);
    }

    public function getInstalledInfo()
    {
        $file = $this->getDirectory().'/installed.json';
        if (!file_exists($file)) {
            return [];
        }

        return json_decode(file_get_contents($file), true);
    }

    public function updateAll()
    {
        $info = $this->getPackageInfo();
        $installed = $this->getInstalledInfo();

        foreach ($info as $version => $revision) {
            if (array_key_exists($version, $installed) && $installed[$version] == $revision['dist']['reference']) {
                continue;
            }

            $this->bus->dispatch(new UpdateKeylighterMessage($revision,  $this->getDirectory($version)));
        }
    }

    private function getPackageInfo()
    {
        return json_decode(file_get_contents(self::URL), true)['packages']['kadet/keylighter'];
    }

    public function getDirectory($version = null): string
    {
        return $this->ensureDirectoryExists($this->parameters->get('keylighter_dir').DIRECTORY_SEPARATOR.$version);
    }

    private function ensureDirectoryExists($directory)
    {
        $this->filesystem->mkdir($directory, 0755);

        return realpath($directory);
    }

    public function load($version)
    {
        if(!in_array($version, $this->getAvailableVersions())) {
            throw new \RuntimeException("'$version' is not an valid KeyLighter version, available are: ".implode(', ', $this->getAvailableVersions()));
        }

        if (!file_exists($this->getDirectory($version).'/vendor/autoload.php')) {
            throw new \RuntimeException("'$version' has no autoload file generated, maybe it is not installed correctly?");
        }

        require $this->getDirectory($version).'/vendor/autoload.php';

        $this->current = $version;
    }

    public function getCurrent()
    {
        return $this->current;
    }

    public function getKeyLighter()
    {
        if (!class_exists(KeyLighter::class)) {
            $this->load('dev-master');
        }

        return KeyLighter::get();
    }

    public function getCurrentDir()
    {
        return $this->getDirectory($this->current);
    }
}
