<?php
/**
 * @package   Essentials YOOtheme Pro 2.2.16 build 0813.1608
 * @author    ZOOlanders https://www.zoolanders.com
 * @copyright Copyright (C) Joolanders, SL
 * @license   http://www.gnu.org/licenses/gpl.html GNU/GPL
 */

namespace ZOOlanders\YOOessentials\Storage\Adapter\FTP;

use ZOOlanders\YOOessentials\Storage\StorageAdapter;
use ZOOlanders\YOOessentials\Storage\StorageConfigurationInvalidException;
use ZOOlanders\YOOessentials\Vendor\League\Flysystem\FilesystemAdapter;
use ZOOlanders\YOOessentials\Vendor\League\Flysystem\FilesystemException;
use ZOOlanders\YOOessentials\Vendor\League\Flysystem\PhpseclibV2\SftpAdapter;
use ZOOlanders\YOOessentials\Vendor\League\Flysystem\PhpseclibV2\SftpConnectionProvider;

class SFTPStorageAdapter extends StorageAdapter
{
    public function adapter(array $config = []): FilesystemAdapter
    {
        return new SftpAdapter(
            new SftpConnectionProvider(
                $config['host'] ?? '127.0.0.1', // host (required)
            $config['username'] ?? '', // username (required)
            $config['password'] ?? null, // password (optional, default: null) set to null if privateKey is used
            $config['privateKey'] ?? null, // private key (optional, default: null) can be used instead of password, set to null if password is set
            $config['passphrase'] ?? null, // passphrase (optional, default: null), set to null if privateKey is not used or has no passphrase
            $config['port'] ?? 22, // port (optional, default: 22)
            ),
            $this->fixRoot($config['root'] ?? '/'), // root path (required)
        );
    }

    public function validateConfig(array $config): void
    {
        $host = $config['host'] ?? null;
        $username = $config['username'] ?? null;
        $root = $config['root'] ?? '';

        if (!$host) {
            throw new StorageConfigurationInvalidException('Host is required.');
        }

        if (!$username) {
            throw new StorageConfigurationInvalidException('Username is required.');
        }

        try {
            // Weird, but this way we intercept any error when actually reading the list of files
            foreach ($this->adapter($config)->listContents($root, false) as $file) {
                return;
            }
        } catch (FilesystemException $e) {
            throw new StorageConfigurationInvalidException($e->getMessage());
        }

        throw new StorageConfigurationInvalidException('Directory does not exist.');
    }

    private function fixRoot($root): string
    {
        if (strlen(trim($root)) <= 0) {
            $root = '';
        }

        if (substr($root, 0, 1) === '/') {
            $root = substr($root, 1);
        }

        return $root;
    }
}
