-- Migration 113: Connector Type Inference
-- Füllt fehlende connector_type aus zwei Quellen:
--   1. IEEE/MSA Lookup-Tabelle (exakt, nach reach range)
--   2. Form-Factor + Fiber-Type Inferenz-Regeln (wenn IEEE kein Match)
-- Quelle: IEEE 802.3, SFF-8472, MSA specs, industry standard practices

-- ── Quelle 1: IEEE Lookup (reach-based, exakt) ──────────────────────────────
UPDATE transceivers t SET
  connector_type = (
    SELECT il.connector_type
    FROM ieee_wavelength_lookup il
    WHERE UPPER(il.form_factor) = UPPER(t.form_factor)
      AND il.speed_gbps = ROUND(t.speed_gbps::NUMERIC, 2)
      AND UPPER(il.fiber_type) = UPPER(t.fiber_type)
      AND il.reach_min_m <= t.reach_meters
      AND il.reach_max_m >= t.reach_meters
    ORDER BY il.reach_max_m ASC  -- Prefer tightest range match
    LIMIT 1
  )
WHERE t.connector_type IS NULL
  AND t.form_factor IS NOT NULL
  AND t.speed_gbps IS NOT NULL
  AND t.fiber_type IS NOT NULL
  AND t.reach_meters IS NOT NULL
  AND t.reach_meters > 0;

DO $$
DECLARE v INTEGER;
BEGIN
  SELECT COUNT(*) INTO v FROM transceivers WHERE connector_type IS NOT NULL
    AND connector_type = (
      SELECT il.connector_type FROM ieee_wavelength_lookup il
      WHERE UPPER(il.form_factor) = UPPER(transceivers.form_factor) LIMIT 1
    );
  RAISE NOTICE 'After IEEE lookup: approx % connector_type values now set', v;
END $$;

-- ── Quelle 2: Form-Factor + Fiber-Type Inferenz ──────────────────────────────
-- Regeln basierend auf IEEE 802.3 und MSA Spezifikationen:
--   SFP/SFP+/SFP28/XFP   + SMF/MMF           → LC (dual fiber, standard single-mode)
--   QSFP+                 + MMF               → MPO-12 (SR4 = 4x parallel fiber)
--   QSFP+                 + SMF, reach ≤ 2km  → MPO-12 (PSM4 = parallel SMF)
--   QSFP+                 + SMF, reach > 2km  → LC (LR4 = CWDM4 on 2 fibers)
--   QSFP28                + MMF               → MPO-12 (SR4)
--   QSFP28                + SMF, reach ≤ 2km  → MPO-12 (DR/PSM4)
--   QSFP28                + SMF, reach > 2km  → LC (LR4/CWDM4)
--   QSFP56                + MMF               → MPO-16 (SR4 on 200G)
--   QSFP56                + SMF               → LC (FR4/LR4)
--   QSFP-DD/QSFP-DD800    + MMF               → MPO-16 (SR8)
--   QSFP-DD/QSFP-DD800    + SMF, reach ≤ 2km  → MPO-12 (DR4/DR8)
--   QSFP-DD/QSFP-DD800    + SMF, reach > 2km  → LC (FR4/LR4)
--   OSFP                  + MMF               → MPO-16 (SR8)
--   OSFP                  + SMF, reach ≤ 2km  → MPO-12 (DR8)
--   OSFP                  + SMF, reach > 2km  → LC (FR4/LR4)
--   any                   + Copper            → RJ45
--   any                   + DAC               → NULL (native electrical, no fiber connector)
--   any                   + AOC               → LC (optical fan-out)

UPDATE transceivers SET
  connector_type = CASE
    -- Copper BASE-T
    WHEN UPPER(fiber_type) IN ('COPPER', 'COPPER/RJ45') THEN 'RJ45'

    -- DAC = Direct Attach Copper, no optical connector
    WHEN UPPER(fiber_type) = 'DAC' THEN 'DAC'

    -- AOC = Active Optical Cable, LC fan-out connectors
    WHEN UPPER(fiber_type) = 'AOC' THEN 'LC'

    -- Single-lane form factors: always LC for optical
    WHEN UPPER(form_factor) IN ('SFP', 'SFP+', 'SFP28', 'XFP', 'SFP56')
         AND UPPER(fiber_type) IN ('SMF', 'MMF') THEN 'LC'

    -- QSFP+ (40G)
    WHEN UPPER(form_factor) = 'QSFP+'
         AND UPPER(fiber_type) = 'MMF' THEN 'MPO-12'
    WHEN UPPER(form_factor) = 'QSFP+'
         AND UPPER(fiber_type) = 'SMF'
         AND reach_meters IS NOT NULL AND reach_meters <= 2000 THEN 'MPO-12'
    WHEN UPPER(form_factor) = 'QSFP+'
         AND UPPER(fiber_type) = 'SMF'
         AND (reach_meters IS NULL OR reach_meters > 2000) THEN 'LC'

    -- QSFP28 (100G)
    WHEN UPPER(form_factor) = 'QSFP28'
         AND UPPER(fiber_type) = 'MMF' THEN 'MPO-12'
    WHEN UPPER(form_factor) = 'QSFP28'
         AND UPPER(fiber_type) = 'SMF'
         AND reach_meters IS NOT NULL AND reach_meters <= 2000 THEN 'MPO-12'
    WHEN UPPER(form_factor) = 'QSFP28'
         AND UPPER(fiber_type) = 'SMF'
         AND (reach_meters IS NULL OR reach_meters > 2000) THEN 'LC'

    -- QSFP56 (200G)
    WHEN UPPER(form_factor) = 'QSFP56'
         AND UPPER(fiber_type) = 'MMF' THEN 'MPO-16'
    WHEN UPPER(form_factor) = 'QSFP56'
         AND UPPER(fiber_type) = 'SMF' THEN 'LC'

    -- QSFP-DD / QSFP-DD800 (400G/800G)
    WHEN UPPER(form_factor) IN ('QSFP-DD', 'QSFP-DD800')
         AND UPPER(fiber_type) = 'MMF' THEN 'MPO-16'
    WHEN UPPER(form_factor) IN ('QSFP-DD', 'QSFP-DD800')
         AND UPPER(fiber_type) = 'SMF'
         AND reach_meters IS NOT NULL AND reach_meters <= 2000 THEN 'MPO-12'
    WHEN UPPER(form_factor) IN ('QSFP-DD', 'QSFP-DD800')
         AND UPPER(fiber_type) = 'SMF'
         AND (reach_meters IS NULL OR reach_meters > 2000) THEN 'LC'

    -- OSFP (800G+)
    WHEN UPPER(form_factor) = 'OSFP'
         AND UPPER(fiber_type) = 'MMF' THEN 'MPO-16'
    WHEN UPPER(form_factor) = 'OSFP'
         AND UPPER(fiber_type) = 'SMF'
         AND reach_meters IS NOT NULL AND reach_meters <= 2000 THEN 'MPO-12'
    WHEN UPPER(form_factor) = 'OSFP'
         AND UPPER(fiber_type) = 'SMF'
         AND (reach_meters IS NULL OR reach_meters > 2000) THEN 'LC'

    -- CFP/CFP2/CFP4 (100G coherent)
    WHEN UPPER(form_factor) IN ('CFP', 'CFP2', 'CFP4') THEN 'LC'

    ELSE NULL
  END
WHERE connector_type IS NULL
  AND form_factor IS NOT NULL
  AND fiber_type IS NOT NULL;

-- ── Completeness neu berechnen ───────────────────────────────────────────────
UPDATE transceivers SET
  data_completeness = calc_data_completeness(
    form_factor, speed_gbps, fiber_type,
    reach_meters, wavelength_tx_nm, connector_type
  ),
  enrichment_needed = (
    form_factor IS NULL OR speed_gbps IS NULL OR
    fiber_type IS NULL OR reach_meters IS NULL OR
    wavelength_tx_nm IS NULL OR connector_type IS NULL
  ),
  enrichment_fields = ARRAY_REMOVE(ARRAY[
    CASE WHEN form_factor IS NULL THEN 'form_factor' END,
    CASE WHEN speed_gbps IS NULL THEN 'speed_gbps' END,
    CASE WHEN fiber_type IS NULL THEN 'fiber_type' END,
    CASE WHEN reach_meters IS NULL OR reach_meters = 0 THEN 'reach_meters' END,
    CASE WHEN wavelength_tx_nm IS NULL THEN 'wavelength_tx_nm' END,
    CASE WHEN connector_type IS NULL THEN 'connector_type' END
  ], NULL);

-- ── Statistik ────────────────────────────────────────────────────────────────
DO $$
DECLARE
  total_cnt       INTEGER;
  complete_cnt    INTEGER;
  missing_conn    INTEGER;
  missing_wl      INTEGER;
  fx_complete     INTEGER;
BEGIN
  SELECT COUNT(*) INTO total_cnt FROM transceivers;
  SELECT COUNT(*) INTO complete_cnt FROM transceivers WHERE enrichment_needed = FALSE;
  SELECT COUNT(*) INTO missing_conn FROM transceivers WHERE connector_type IS NULL;
  SELECT COUNT(*) INTO missing_wl   FROM transceivers WHERE wavelength_tx_nm IS NULL;
  SELECT COUNT(*) INTO fx_complete
    FROM transceivers t JOIN vendors v ON v.id = t.vendor_id
    WHERE UPPER(v.name) LIKE '%FLEXOPTIX%' AND enrichment_needed = FALSE;

  RAISE NOTICE 'Migration 113 complete:';
  RAISE NOTICE '  Total transceivers:      %', total_cnt;
  RAISE NOTICE '  Fully complete:          %', complete_cnt;
  RAISE NOTICE '  Still missing connector: %', missing_conn;
  RAISE NOTICE '  Still missing wavelength: %', missing_wl;
  RAISE NOTICE '  Flexoptix fully complete: %', fx_complete;
END $$;
