-- +goose Up
-- +goose StatementBegin

-- Unbound zones. zone_type 'local' = local-data records served
-- authoritatively (e.g. eg.cluster). 'forward' = stub-zone forwarded
-- to a specific upstream. The eg.cluster zone is auto-managed by
-- internal/cluster; user-defined zones land here too.
CREATE TABLE IF NOT EXISTS dns_zones (
    id           BIGSERIAL PRIMARY KEY,
    name         TEXT NOT NULL,
    zone_type    TEXT NOT NULL DEFAULT 'local',
    description  TEXT,
    managed_by   TEXT NOT NULL DEFAULT 'user',
    active       BOOLEAN NOT NULL DEFAULT TRUE,
    created_at   TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at   TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    CONSTRAINT dns_zones_name_unique  UNIQUE (name),
    CONSTRAINT dns_zones_type_check   CHECK (zone_type IN ('local', 'forward'))
);

-- DNS records. record_type matches RFC 1035 / RFC 3596 mnemonics
-- (A, AAAA, CNAME, TXT, MX, SRV, ...). value is the record's RDATA in
-- text form (priority + value for MX/SRV are concatenated, e.g.
-- "10 mail.example.com").
CREATE TABLE IF NOT EXISTS dns_records (
    id           BIGSERIAL PRIMARY KEY,
    zone_id      BIGINT NOT NULL REFERENCES dns_zones(id) ON DELETE CASCADE,
    name         TEXT NOT NULL,
    record_type  TEXT NOT NULL,
    value        TEXT NOT NULL,
    ttl          INTEGER NOT NULL DEFAULT 300,
    active       BOOLEAN NOT NULL DEFAULT TRUE,
    created_at   TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at   TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    CONSTRAINT dns_records_type_check CHECK (record_type IN ('A', 'AAAA', 'CNAME', 'TXT', 'MX', 'SRV', 'NS', 'PTR', 'CAA'))
);

CREATE INDEX IF NOT EXISTS idx_dns_records_zone   ON dns_records (zone_id);
CREATE INDEX IF NOT EXISTS idx_dns_records_active ON dns_records (active) WHERE active;

-- +goose StatementEnd

-- +goose Down
-- +goose StatementBegin
DROP TABLE IF EXISTS dns_records;
DROP TABLE IF EXISTS dns_zones;
-- +goose StatementEnd
