<?php

namespace App\Services\Dns;

use App\Models\DnsRecord;
use Illuminate\Support\Facades\Log;
use Throwable;

/**
 * Record ids from the OLD Hetzner DNS API, brought across where that is
 * possible — and left alone where it is not.
 *
 * The cloud API addresses an RRSet by `{name}/{type}`; the old one issued an
 * opaque id like `rec-abc123`. Every id this installation stored before the
 * move is of the old shape, and nothing in the new client can address one.
 *
 * I got this wrong in the first pass. I counted the rows on the DEVELOPMENT
 * database — hosts, dns_records and run_resources, all empty — and wrote that
 * into RrsetId as though it settled the question. It settles nothing: the live
 * server is a different installation with its own rows, and a format change
 * across a schema is not made safe by one machine happening to be empty.
 * (Codex review 2026-07-31, P1.)
 *
 * What can be converted: `dns_records` carries `fqdn` and `type` beside the id,
 * so the RRSet name follows exactly. What cannot: `hosts.dns_record_id` (only a
 * short name is stored, never the fqdn that was published) and the
 * `dns_record_id` run resources (an id and nothing else). Those are handled at
 * the other end — HttpHetznerDnsClient::deleteRecord() lets a legacy id pass
 * with a loud log instead of throwing, so a purge completes rather than dying
 * on the same row for ever.
 *
 * Guessing is deliberately not done. A record whose fqdn is not inside the
 * configured zone is left untouched: it was never something this client could
 * have written, and inventing a name for it would publish a deletion against
 * whatever happens to carry that name today.
 */
class LegacyRecordIds
{
    /** @return int how many rows were rewritten */
    public function migrate(): int
    {
        $rewritten = 0;

        foreach (DnsRecord::query()->get() as $record) {
            if (str_contains((string) $record->record_id, '/')) {
                continue;
            }

            try {
                $id = RrsetId::for((string) $record->fqdn, (string) $record->type);
            } catch (Throwable) {
                // Outside the configured zone, or no zone configured at all.
                // Left exactly as it is — see the class comment.
                continue;
            }

            $record->update(['record_id' => $id]);
            $rewritten++;
        }

        return $rewritten;
    }
}
