<?php

namespace Velis\Filesystem;

use Aws\S3\S3Client;
use Gaufrette\Adapter\Local as LocalAdapter;
use Gaufrette\Filesystem;
use Phalcon\Di\DiInterface;
use Phalcon\Di\ServiceProviderInterface;
use Velis\App;
use Velis\App\Config;
use Velis\Filesystem\Adapter\Local as LocalFilesystem;
use Velis\Filesystem\Adapter\UploadFilesystemFactory;
use Velis\Filesystem\Av\Contract\AvClientInterface;
use Velis\Filesystem\Filesystem as VelisFilesystem;

/**
 * @author Szymon Janaczek <szymon.janaczek@velistech.com>
 */
final class FilesystemServiceProvider implements ServiceProviderInterface
{
    public function register(DiInterface $di): void
    {
        $di->set(S3Client::class, function (Config $config) {
            return new S3Client([
                'credentials' => [
                    'key' => $config->accessKeyId,
                    'secret' => $config->secretAccessKey,
                ],
                'version' => 'latest',
                'region' => $config->region,
            ]);
        });

        $di->set('filesystem', function () use ($di): FilesystemInterface {
            $factory = new FilesystemFactory(di: App::$di);

            return $factory->createUpload();
        });

        $di->set('filesystem.app', function (): FilesystemInterface {
            $basePath = ROOT_PATH;

            if (!class_exists(Filesystem::class)) {
                return new VelisFilesystem($basePath);
            }

            $adapter = new LocalAdapter($basePath);
            $filesystem = new Filesystem($adapter);

            return new LocalFilesystem($filesystem, $basePath);
        });

        $di->set('filesystem.upload', function (): FilesystemInterface {
            $config = App::$config;
            $cache = App::getService('cache');
            $avClient = App::getService(AvClientInterface::class);

            $uploadPath = $config->upload->alternativeDir;
            if (!$uploadPath) {
                $uploadPath = DATA_PATH;
            }

            $uploadFilesystemFactory = new UploadFilesystemFactory(
                config: $config,
                cache: $cache,
                avClient: $avClient,
            );

            return $uploadFilesystemFactory->get($uploadPath);
        });
    }
}
