-- Fleet DNS: zones, locations, nodes, aliases, sync

CREATE TABLE IF NOT EXISTS zones (
  id TEXT PRIMARY KEY NOT NULL,
  cf_zone_id TEXT,
  name TEXT NOT NULL UNIQUE,
  role TEXT NOT NULL DEFAULT 'routing',
  naming_template TEXT NOT NULL DEFAULT '{loc}-{role}{nn}.{zone}',
  default_ttl INTEGER NOT NULL DEFAULT 300,
  last_sync_at TEXT,
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
  updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);

CREATE TABLE IF NOT EXISTS locations (
  id TEXT PRIMARY KEY NOT NULL,
  code TEXT NOT NULL UNIQUE,
  name TEXT NOT NULL,
  country TEXT,
  sort_order INTEGER NOT NULL DEFAULT 0,
  created_at TEXT NOT NULL DEFAULT (datetime('now'))
);

CREATE TABLE IF NOT EXISTS nodes (
  id TEXT PRIMARY KEY NOT NULL,
  zone_id TEXT NOT NULL REFERENCES zones(id) ON DELETE CASCADE,
  location_id TEXT NOT NULL REFERENCES locations(id),
  hostname TEXT NOT NULL,
  role TEXT NOT NULL,
  index_num INTEGER NOT NULL DEFAULT 1,
  provider_tag TEXT,
  notes TEXT,
  sync_status TEXT NOT NULL DEFAULT 'pending',
  cf_a_record_id TEXT,
  cf_aaaa_record_id TEXT,
  last_error TEXT,
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
  updated_at TEXT NOT NULL DEFAULT (datetime('now')),
  UNIQUE (zone_id, hostname)
);

CREATE INDEX IF NOT EXISTS idx_nodes_zone ON nodes(zone_id);
CREATE INDEX IF NOT EXISTS idx_nodes_location ON nodes(location_id);
CREATE INDEX IF NOT EXISTS idx_nodes_sync ON nodes(sync_status);

CREATE TABLE IF NOT EXISTS node_addresses (
  id TEXT PRIMARY KEY NOT NULL,
  node_id TEXT NOT NULL REFERENCES nodes(id) ON DELETE CASCADE,
  family TEXT NOT NULL,
  ip TEXT NOT NULL,
  UNIQUE (node_id, family)
);

CREATE TABLE IF NOT EXISTS aliases (
  id TEXT PRIMARY KEY NOT NULL,
  zone_id TEXT NOT NULL REFERENCES zones(id) ON DELETE CASCADE,
  name TEXT NOT NULL,
  purpose TEXT NOT NULL DEFAULT 'geo',
  mode TEXT NOT NULL DEFAULT 'primary',
  target_node_id TEXT NOT NULL REFERENCES nodes(id) ON DELETE RESTRICT,
  sync_status TEXT NOT NULL DEFAULT 'pending',
  cf_record_id TEXT,
  last_error TEXT,
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
  updated_at TEXT NOT NULL DEFAULT (datetime('now')),
  UNIQUE (zone_id, name)
);

CREATE INDEX IF NOT EXISTS idx_aliases_zone ON aliases(zone_id);
CREATE INDEX IF NOT EXISTS idx_aliases_target ON aliases(target_node_id);
CREATE INDEX IF NOT EXISTS idx_aliases_sync ON aliases(sync_status);

CREATE TABLE IF NOT EXISTS sync_jobs (
  id TEXT PRIMARY KEY NOT NULL,
  zone_id TEXT NOT NULL REFERENCES zones(id) ON DELETE CASCADE,
  status TEXT NOT NULL DEFAULT 'pending',
  diff_json TEXT,
  error TEXT,
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
  finished_at TEXT
);

CREATE INDEX IF NOT EXISTS idx_sync_jobs_zone ON sync_jobs(zone_id);

CREATE TABLE IF NOT EXISTS sync_events (
  id TEXT PRIMARY KEY NOT NULL,
  job_id TEXT NOT NULL REFERENCES sync_jobs(id) ON DELETE CASCADE,
  kind TEXT NOT NULL,
  record_name TEXT,
  record_type TEXT,
  detail TEXT,
  created_at TEXT NOT NULL DEFAULT (datetime('now'))
);

CREATE INDEX IF NOT EXISTS idx_sync_events_job ON sync_events(job_id);

CREATE TABLE IF NOT EXISTS ignored_orphans (
  id TEXT PRIMARY KEY NOT NULL,
  zone_id TEXT NOT NULL REFERENCES zones(id) ON DELETE CASCADE,
  record_name TEXT NOT NULL,
  record_type TEXT NOT NULL,
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
  UNIQUE (zone_id, record_name, record_type)
);

-- Seed locations (IATA / routing codes from naming doc)
INSERT OR IGNORE INTO locations (id, code, name, country, sort_order) VALUES
  ('loc-msk', 'msk', 'Москва', 'RU', 10),
  ('loc-fra', 'fra', 'Франкфурт', 'DE', 20),
  ('loc-ams', 'ams', 'Амстердам', 'NL', 30),
  ('loc-hel', 'hel', 'Хельсинки', 'FI', 40),
  ('loc-par', 'par', 'Париж', 'FR', 50);

-- Extend settings defaults for naming / TTL
ALTER TABLE app_settings ADD COLUMN default_ttl INTEGER NOT NULL DEFAULT 300;
ALTER TABLE app_settings ADD COLUMN naming_template TEXT NOT NULL DEFAULT '{loc}-{role}{nn}.{zone}';
ALTER TABLE app_settings ADD COLUMN proxied_lock INTEGER NOT NULL DEFAULT 1;
