<?php

declare(strict_types=1);

namespace PpPhp\Core\Databases\Drivers;

/**
 * How a database actually gets created on a given server.
 *
 * There are three ways, and they are not interchangeable in the details:
 *
 *   • sql          — we hold a privileged MySQL login and run CREATE DATABASE.
 *                    Works on a VPS or localhost. Fails on shared hosting, where
 *                    port 3306 is firewalled and the account has no CREATE grant.
 *   • cpanel       — the cPanel UAPI performs the creation for us over HTTPS.
 *   • directadmin  — the DirectAdmin API does the same.
 *
 * The panels differ from raw SQL in one way that matters everywhere: they FORCE
 * a `<account>_` prefix onto every database and user name. Ask for `mydb` and
 * you get `ppradhan_mydb`. A driver therefore returns the names that were
 * actually created rather than the ones it was asked for, and the caller must
 * store those — assuming otherwise is the single easiest way to end up with a
 * catalogue that does not match reality.
 */
interface ProvisionDriver
{
    /**
     * Verify the credentials and report what this server can do.
     *
     * Must never throw: a failed test is a normal answer the owner needs to see.
     *
     * @return array{
     *   success:bool, message:string,
     *   canCreateDb:bool, canCreateUser:bool,
     *   prefix:string,        // the forced name prefix, '' when there is none
     *   maxNameLength:int,    // 0 when unknown/unlimited
     *   detail?:array<string,mixed>
     * }
     */
    public function test(): array;

    /**
     * Create a database and a login that can use it.
     *
     * @param string $desiredDb   name WITHOUT any panel prefix
     * @param string $desiredUser name WITHOUT any panel prefix
     * @param string $password    already generated and policy-safe
     *
     * @return array{
     *   success:bool, message:string,
     *   dbName?:string,     // the name that actually exists now
     *   dbUser?:string,     // ditto
     *   dedicated?:bool     // false when the login is shared rather than per-database
     * }
     */
    public function createDatabase(string $desiredDb, string $desiredUser, string $password): array;

    /**
     * Remove a database and, when the driver made one, its dedicated login.
     * Names are the REAL ones as stored — already prefixed.
     *
     * @return array{success:bool, message:string}
     */
    public function dropDatabase(string $dbName, string $dbUser = ''): array;

    /**
     * How an application connects to a database this driver made. Panels create
     * databases on their own host, reachable on the normal MySQL port from the
     * panel's own network — which is why this is asked of the driver rather than
     * assumed by the caller.
     *
     * @return array{host:string, port:int}
     */
    public function connectionTarget(): array;

    /** Short identifier stored on the server row: sql | cpanel | directadmin. */
    public function id(): string;
}
