<?php

declare(strict_types=1);

namespace PpPhp\Core\Storage;

/**
 * StorageDriver — the single contract every storage backend implements.
 *
 * A "driver" is a place files live: the self-hosted server (LocalDriver), an
 * S3-compatible bucket, Google Drive, OneDrive… The File/Image plugin, the
 * generated app's api/upload.php, and the Image/File view controls all talk to
 * a driver through THIS interface and never to a backend directly — so adding a
 * new backend is one new file, with zero changes to the UI or the save path.
 *
 * Every method works with a portable "reference" array (see StorageRef): the
 * small JSON blob stored in the record column. A driver's job is to turn a
 * freshly-uploaded temp file into a reference (put), and to resolve a reference
 * back into a URL / stream / deletion later.
 *
 * Implementations MUST be stateless enough to be constructed from a connection
 * config array (see StorageConfig) — StorageRegistry owns their lifecycle.
 */
interface StorageDriver
{
    /**
     * The driver id stored inside every reference this driver produces
     * (e.g. 'local', 's3', 'gdrive', 'onedrive'). Lowercase, [a-z0-9_].
     */
    public static function id(): string;

    /**
     * Store a validated temp file and return a StorageRef array.
     *
     * $tmpPath is a path on local disk (a $_FILES tmp_name, or a reassembled
     * chunk file). $meta carries at least: name, mime, size, ext; optionally
     * w, h (image dimensions), thumbTmp (a generated thumbnail temp path),
     * folder (a sub-path hint), field, table.
     *
     * @return array The reference to persist (StorageRef::encode ready).
     */
    public function put(string $tmpPath, array $meta): array;

    /**
     * Public or signed URL for a stored reference. $opts may carry:
     *   inline (bool)     — Content-Disposition intent for the file endpoint
     *   thumb  (bool)     — resolve the thumbnail variant when present
     *   ttl    (int secs) — desired lifetime for a signed URL
     * A private/cloud driver returns a time-limited signed URL; a public local
     * file returns a direct /uploads/… URL.
     */
    public function url(array $ref, array $opts = []): string;

    /**
     * Open a read stream for the stored object, or null if unavailable.
     * Used by the file endpoint to proxy private/cloud objects.
     *
     * @return resource|null
     */
    public function openStream(array $ref);

    /** Permanently delete the stored object (and its thumb). True on success. */
    public function delete(array $ref): bool;

    /** Whether the referenced object still exists in the backend. */
    public function exists(array $ref): bool;

    /**
     * Capability flags the UI + build branch on. Keys (all optional):
     *   directUpload (bool) — client can upload straight to the backend
     *   publicUrl    (bool) — url() can be a durable public link
     *   signedUrl    (bool) — url() supports time-limited signed links
     *   chunked      (bool) — backend/endpoint accepts resumable chunks
     *   maxBytes     (int)  — hard per-object size ceiling, 0 = unlimited
     *
     * @return array<string,mixed>
     */
    public function capabilities(): array;
}
