<?php

namespace App\Services\Dns;

use RuntimeException;

/**
 * Writes one file per host into config('provisioning.dns.hosts_dir') — an
 * /etc/hosts-format line ("<ip> <fqdn>") per entry, in the directory dnsmasq's
 * --hostsdir watches via inotify (see vpn-dns in docker-compose.yml). No
 * restart, no reload call: the file landing on disk IS the publish.
 *
 * The directory is shared with the app's own containers over a plain Docker
 * volume, not SSH — unlike SshTraefikWriter, everything that touches it runs
 * on the same Docker host. Left world-writable/readable (0775/0664) because
 * whichever container touches it first (queue-provisioning as root in
 * production, www-data under `app`) must not lock the other out.
 */
class FileHostDnsDirectory implements HostDnsDirectory
{
    public function write(string $name, string $fqdn, string $ip): void
    {
        $this->ensureDir();

        $path = $this->path($name);

        if (@file_put_contents($path, "{$ip} {$fqdn}\n") === false) {
            throw new RuntimeException("Could not write DNS hosts entry: {$path}");
        }

        @chmod($path, 0664);
    }

    public function remove(string $name): void
    {
        $path = $this->path($name);

        // Nothing to do is not a failure — a host whose name was never
        // written (or already removed) still has to purge cleanly.
        if (is_file($path) && ! @unlink($path)) {
            throw new RuntimeException("Could not remove DNS hosts entry: {$path}");
        }
    }

    private function ensureDir(): void
    {
        $dir = $this->dir();

        if (is_dir($dir)) {
            return;
        }

        if (! @mkdir($dir, 0775, true) && ! is_dir($dir)) {
            throw new RuntimeException("Could not create DNS hosts directory: {$dir}");
        }

        @chmod($dir, 0775);
    }

    private function path(string $name): string
    {
        return rtrim($this->dir(), '/')."/{$name}.hosts";
    }

    private function dir(): string
    {
        return (string) config('provisioning.dns.hosts_dir');
    }
}
