-- This file control sum
SET vars.csum TO :'csum';
-- This zone copy hostname
SET vars.ns   TO :'NSERVER';

DO $$
-- Наполнение

DECLARE
  v_domain    text;                               -- domain name
  v_domain_id integer;                            -- internal domain id
  v_ns_admin  text := 'hostmaster.example.ru';    -- master DNS admin email
  v_soa       text;                               -- zone SOA
  v_prefixes cidr[] := ARRAY[
    '10.0.0.0/8',         -- Private-Use Networks
    '100.64.0.0/10',      -- CG-NAT
    '127.0.0.0/8',        -- Loopback
    '172.16.0.0/12',      -- LLA
    '169.254.0.0/16',     -- Private-Use Networks
    '192.0.0.0/24',       -- IETF Protocol Assignments
    '192.0.2.0/24',       -- TEST-NET-1
    '192.88.99.0/24',     -- 6to4 Relay Anycast
    '192.168.0.0/16',     -- Private-Use Networks
    '198.18.0.0/15',      -- Network Interconnect Device Benchmark Testing
    '198.51.100.0/24',    -- TEST-NET-2
    '203.0.113.0/24'      -- TEST-NET-3
    ];
  v_prefixes24 cidr[];
  v_prefix cidr;
  v_arr text[];

BEGIN
  -- пересобираем список префиксов по /24
  -- ToDo: префиксы выходящие за границы /8 =< prefix < /24 пропускать
  FOREACH v_prefix IN ARRAY v_prefixes LOOP
    -- получили размерность
    FOR i IN 0 .. 2^(24 - masklen(v_prefix))-1 LOOP
      -- добавили каждую /24
      v_prefixes24 := ARRAY_APPEND(v_prefixes24, set_masklen(v_prefix + 256 * i, 24));
      -- RAISE NOTICE '% %: %',  v_prefix, i, set_masklen(v_prefix + 256 * i, 24);
    END LOOP;
  END LOOP;

  FOREACH v_prefix IN ARRAY v_prefixes24 LOOP
    -- собираем имя зоны
	  v_domain := concat_ws('.', -- собираем полностью итоговый v_domain в формате $oct3.$oct2.$oct1.in-addr.arpa
      array_to_string( -- результат превращаем в текст
        array_reverse( -- разворачиваем массив в обратном направлении для in-addr.arpa
          trim_array( -- отрезаем от массива последний октет с маской, так как для /24 в in-addr.arpa надо 3 октета
            string_to_array(v_prefix::text, '.'), -- v_prefix переводим в text и разбираем в массив через '.'
						1 
					)
				),'.'
			),
			'in-addr.arpa'
		);
    
    SELECT INTO v_domain_id id FROM domains WHERE name = v_domain;
      IF NOT FOUND THEN
        -- зона отсутствует, будем генерить зону по умолчанию
	    RAISE NOTICE 'Stub generator for prefix:% zone:%', v_prefix, v_domain;
      ELSE
        -- зона уже создана, пропустить stub-функционал
        RAISE NOTICE 'zone:% already exists, skip stub generation', v_domain;
        CONTINUE;
      END IF;

    /* 
       чексуммы у зоны нет, поэтому достаточно будет первого запуска по
       файлу со спецификой зоны, чтобы затереть зону-заглушку
       получаем/создаём домен ID
    */
    v_domain_id := domain_id(v_domain);

    -- собираем SOA
    v_soa := soa_mk(v_domain_id, v_ns_admin);
    
    -- в принципе если мы здесь, то предполагается, что зоны такой не существовало
    -- и записей, соответственно, нет. но тем не менее
    DELETE FROM records WHERE domain_id = v_domain_id;

    -- генерим зону по умолчанию
    INSERT INTO records (domain_id, name, ttl, type, prio, content) VALUES 
    (v_domain_id, v_domain, 10800,  'SOA', 0, v_soa)
  , (v_domain_id, v_domain, 10800, 'NS', 0, 'ns1.example.ru')
  , (v_domain_id, v_domain, 10800, 'NS', 0, 'ns2.example.ru')
  ;
  END LOOP;
END;
$$;
