-- Migration 2026-04-16 : enrichissement applications IODA + table qualys_missing_servers
-- Idempotent (re-jouable sans casse)

BEGIN;

-- =========================================================================
-- 1) Extension table applications avec champs IODA
-- =========================================================================
ALTER TABLE applications ADD COLUMN IF NOT EXISTS ioda_libelle      varchar(200);
ALTER TABLE applications ADD COLUMN IF NOT EXISTS ioda_lib_court    varchar(50);
ALTER TABLE applications ADD COLUMN IF NOT EXISTS ioda_code_pos     varchar(20);
ALTER TABLE applications ADD COLUMN IF NOT EXISTS ioda_type         varchar(50);
ALTER TABLE applications ADD COLUMN IF NOT EXISTS ioda_statut       varchar(50);
ALTER TABLE applications ADD COLUMN IF NOT EXISTS ioda_alias        text;
ALTER TABLE applications ADD COLUMN IF NOT EXISTS ioda_perimetre    varchar(100);
ALTER TABLE applications ADD COLUMN IF NOT EXISTS ioda_dept_domaine varchar(200);
ALTER TABLE applications ADD COLUMN IF NOT EXISTS ioda_resp_metier  varchar(100);
ALTER TABLE applications ADD COLUMN IF NOT EXISTS ioda_resp_dsi     varchar(100);
ALTER TABLE applications ADD COLUMN IF NOT EXISTS ioda_nb_components integer;
ALTER TABLE applications ADD COLUMN IF NOT EXISTS ioda_commentaire  text;
ALTER TABLE applications ADD COLUMN IF NOT EXISTS ioda_imported_at  timestamptz;

CREATE UNIQUE INDEX IF NOT EXISTS applications_ioda_libelle_uniq
    ON applications (ioda_libelle) WHERE ioda_libelle IS NOT NULL;

COMMENT ON COLUMN applications.ioda_libelle      IS 'Libellé service métier IODA (clé d''import)';
COMMENT ON COLUMN applications.ioda_code_pos     IS 'Code zone POS IODA (TRA, ADV, …)';
COMMENT ON COLUMN applications.ioda_resp_metier  IS 'Responsable Service Métier (à notifier patching)';
COMMENT ON COLUMN applications.ioda_resp_dsi     IS 'Responsable Service DSI (à notifier patching)';

-- =========================================================================
-- 2) Table qualys_missing_servers (serveurs absents de Qualys + raison)
-- =========================================================================
CREATE TABLE IF NOT EXISTS qualys_missing_servers (
    id                serial PRIMARY KEY,
    hostname          varchar(255) NOT NULL,
    hostname_norm     varchar(255) GENERATED ALWAYS AS (lower(hostname)) STORED,
    environnement     varchar(50),
    sources_present   varchar(100),         -- ex: "Cyberark+S1+ITOP"
    in_cyberark       boolean DEFAULT false,
    in_sentinel       boolean DEFAULT false,
    in_itop           boolean DEFAULT false,
    server_id         integer REFERENCES servers(id) ON DELETE SET NULL,
    reason_category   varchar(30),          -- appliance | ot_scada | virtualisation | embedded | oubli | decom | inconnu | other
    reason_detail     text,
    status            varchar(20) DEFAULT 'a_traiter',  -- a_traiter | a_enroler | exempt | enrole | decom
    priority          smallint DEFAULT 3,   -- 1 (urgent) → 5 (faible)
    notes             text,
    source_file       varchar(100),         -- fichier d'origine
    last_seen_at      timestamptz DEFAULT now(),
    created_at        timestamptz DEFAULT now(),
    updated_at        timestamptz DEFAULT now(),
    CONSTRAINT qms_status_check CHECK (status IN ('a_traiter','a_enroler','exempt','enrole','decom')),
    CONSTRAINT qms_reason_check CHECK (reason_category IS NULL OR reason_category IN
        ('appliance','ot_scada','virtualisation','embedded','oubli','decom','inconnu','other'))
);

CREATE UNIQUE INDEX IF NOT EXISTS qms_hostname_norm_uniq ON qualys_missing_servers (hostname_norm);
CREATE INDEX IF NOT EXISTS qms_status_idx       ON qualys_missing_servers (status);
CREATE INDEX IF NOT EXISTS qms_reason_idx       ON qualys_missing_servers (reason_category);
CREATE INDEX IF NOT EXISTS qms_server_id_idx    ON qualys_missing_servers (server_id);

COMMENT ON TABLE  qualys_missing_servers IS 'Serveurs détectés ailleurs (CA/S1/iTop) mais absents de Qualys + raison';
COMMENT ON COLUMN qualys_missing_servers.reason_category IS 'appliance, ot_scada, virtualisation (ESXi), embedded, oubli (à enrôler), decom, inconnu, other';
COMMENT ON COLUMN qualys_missing_servers.status          IS 'a_traiter, a_enroler, exempt (légitimement hors Qualys), enrole (fait), decom';
COMMENT ON COLUMN qualys_missing_servers.priority        IS '1 urgent → 5 faible (auto-calc selon sources)';

-- Trigger updated_at
CREATE OR REPLACE FUNCTION qms_set_updated_at() RETURNS trigger AS $$
BEGIN NEW.updated_at = now(); RETURN NEW; END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS qms_updated_at_trg ON qualys_missing_servers;
CREATE TRIGGER qms_updated_at_trg
    BEFORE UPDATE ON qualys_missing_servers
    FOR EACH ROW EXECUTE FUNCTION qms_set_updated_at();

COMMIT;
