/**
 * Demo Oracle — sessions actives et operations longues (rafraichissement 10 s).
 * Lit sa configuration dans window.DemoOracleReport.realtimeSessions.
 *
 * Portage de modules/oracle/assets/js/report-realtime-sessions.js. Trois
 * choses ont disparu, avec le code serveur qui les servait :
 *
 *   - l'arret de session : bouton, fenetre de confirmation, POST. Le bouton
 *     est toujours dessine, mais desactive ;
 *   - le tableau SQL Monitor et ses liens vers les rapports DBMS_SQLTUNE ;
 *
 * Le menu contextuel sur un SQL_ID est conserve, detail SQL compris : cette
 * page-la fait partie de la demonstration.
 */
(function () {
'use strict';

var config = (window.DemoOracleReport && window.DemoOracleReport.realtimeSessions) || {};

/* ── Constants ───────────────────────────────────────────────────────────── */
var BASE_URL       = config.baseUrl      || '';
var SQL_DETAIL     = config.sqlDetailUrl || '';
var T              = config.T            || {};

// Nombre de colonnes des deux tableaux, colonne d'arret comprise. Fige : la
// demonstration n'a pas de niveaux de droits, la colonne est toujours la.
var COL_COUNT      = 10;

var _refreshTimer = null;
var _tickTimer    = null;
var _cd           = 10;

/* ── Helpers ─────────────────────────────────────────────────────────────── */
function escapeHtml(s) {
    return String(s == null ? '' : s)
        .replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')
        .replace(/"/g,'&quot;').replace(/'/g,'&#039;');
}
function fmtDuration(sec) {
    sec = Math.max(0, parseInt(sec, 10) || 0);
    var h = Math.floor(sec / 3600);
    var m = Math.floor((sec % 3600) / 60);
    var s = sec % 60;
    if (h > 0) return h + 'h ' + (m < 10 ? '0' : '') + m + 'm';
    if (m > 0) return m + 'm ' + (s < 10 ? '0' : '') + s + 's';
    return s + 's';
}
function fmtDateTime(s) {
    if (!s) return '—';
    return s.replace('T', ' ').slice(0, 19);
}

/* ── Right-click context menu ──────────────────────────────────────────── */
var _ctxEl = null;
function _hideCtx() {
    if (_ctxEl) { _ctxEl.remove(); _ctxEl = null; }
}
window.sessShowSqlCtx = function (sqlId, x, y) {
    _hideCtx();
    if (!sqlId || !/^[0-9a-z]{13}$/i.test(sqlId)) return;
    var menu = document.createElement('div');
    menu.style.cssText =
        'position:fixed;z-index:9999;'
        + 'background:var(--color-card-bg,#fff);color:var(--color-text,#222);'
        + 'border:1px solid var(--color-border,#ddd);border-radius:4px;'
        + 'box-shadow:0 2px 10px rgba(0,0,0,.18);padding:.2rem 0;min-width:200px;'
        + 'left:' + Math.min(x, window.innerWidth  - 210) + 'px;'
        + 'top:'  + Math.min(y, window.innerHeight -  80) + 'px';
    function _item(label, action) {
        var li = document.createElement('div');
        li.textContent = label;
        li.style.cssText = 'padding:.38rem .8rem;cursor:pointer;font-size:.84rem;white-space:nowrap;user-select:none';
        li.addEventListener('mouseenter', function () { li.style.background = 'var(--color-primary,#4e79a7)'; li.style.color = '#fff'; });
        li.addEventListener('mouseleave', function () { li.style.background = ''; li.style.color = ''; });
        li.addEventListener('click',      function () { _hideCtx(); action(); });
        menu.appendChild(li);
    }
    _item(T.ctx_open || 'Open SQL detail', function () {
        window.open(SQL_DETAIL + '&sql_id=' + encodeURIComponent(sqlId), '_blank');
    });
    _item(T.ctx_copy || 'Copy SQL_ID', function () {
        if (navigator.clipboard) {
            navigator.clipboard.writeText(sqlId).catch(function () {});
        } else {
            var ta = document.createElement('textarea');
            ta.value = sqlId; ta.style.cssText = 'position:fixed;opacity:0';
            document.body.appendChild(ta); ta.select();
            try { document.execCommand('copy'); } catch (e) {}
            document.body.removeChild(ta);
        }
    });
    document.body.appendChild(menu);
    _ctxEl = menu;
    setTimeout(function () {
        document.addEventListener('click',       _hideCtx, { once: true });
        document.addEventListener('contextmenu', _hideCtx, { once: true });
    }, 0);
};

/* ── Cellule sql_id avec right-click handler ─────────────────────────────── */
function sqlIdCell(sqlId) {
    if (!sqlId) return '<span style="color:var(--color-text-muted)">—</span>';
    var safe = escapeHtml(sqlId);
    return '<code class="sess-sql-id" data-sql-id="' + safe + '" '
        + 'style="cursor:context-menu;user-select:all" '
        + 'oncontextmenu="sessShowSqlCtx(this.dataset.sqlId,event.clientX,event.clientY);event.preventDefault();return false;">'
        + safe + '</code>';
}

/* ── Cellule d'arret de session ──────────────────────────────────────────── */
/*
 * Le bouton est rendu desactive, avec son infobulle : le visiteur voit que la
 * fonction existe. Aucun ecouteur ne lui est attache, et aucun point d'entree
 * ne l'attend cote serveur.
 */
function killBtnCell() {
    return '<td><button type="button" class="btn btn-danger btn-sm" disabled'
        + ' aria-disabled="true" title="' + escapeHtml(T.kill_off || '') + '">'
        + escapeHtml(T.kill || 'Kill') + '</button></td>';
}

/* ── Render: sessions actives ────────────────────────────────────────────── */
function renderSessions(rows) {
    var tbody = document.getElementById('sess-active-tbody');
    if (!tbody) return;
    if (!rows.length) {
        tbody.innerHTML = '<tr><td colspan="' + COL_COUNT + '" style="color:var(--color-text-muted);text-align:center">'
                        + escapeHtml(T.no_data || '—') + '</td></tr>';
        return;
    }
    tbody.innerHTML = rows.map(function (r) {
        var preview = r.sql_preview
            ? '<span title="' + escapeHtml(r.sql_preview) + '" style="font-family:monospace;font-size:.78rem">'
              + escapeHtml(r.sql_preview.length > 80 ? r.sql_preview.slice(0, 80) + '…' : r.sql_preview) + '</span>'
            : '<span style="color:var(--color-text-muted)">—</span>';
        var wcClass = (r.wait_class === 'CPU') ? 'badge-success'
                    : (r.wait_class === 'Idle') ? 'badge-info'
                    : 'badge-warning';
        return '<tr>'
            + '<td>' + r.inst_id + '</td>'
            + '<td><code>' + r.sid + ',' + r.serial_num + '</code></td>'
            + '<td>' + escapeHtml(r.schemaname || r.username || '—') + '</td>'
            + '<td>' + sqlIdCell(r.sql_id) + '</td>'
            + '<td>' + preview + '</td>'
            + '<td>' + escapeHtml(fmtDateTime(r.sql_start)) + '</td>'
            + '<td>' + escapeHtml(fmtDuration(r.duration_sec)) + '</td>'
            + '<td><span class="badge ' + wcClass + '">' + escapeHtml(r.wait_class) + '</span></td>'
            + '<td>' + escapeHtml(r.wait_event || '—') + '</td>'
            + killBtnCell()
            + '</tr>';
    }).join('');
}

/* ── Render: long operations ─────────────────────────────────────────────── */
function renderLongOps(rows) {
    var tbody = document.getElementById('sess-longops-tbody');
    if (!tbody) return;
    if (!rows.length) {
        tbody.innerHTML = '<tr><td colspan="' + COL_COUNT + '" style="color:var(--color-text-muted);text-align:center">'
                        + escapeHtml(T.no_longops || '—') + '</td></tr>';
        return;
    }
    tbody.innerHTML = rows.map(function (r) {
        var pct = (r.totalwork > 0) ? (r.sofar * 100 / r.totalwork) : 0;
        var pctTxt = pct.toFixed(1) + '%';
        var bar = '<div style="display:flex;align-items:center;gap:.4rem;min-width:140px">'
                + '<div style="flex:1;background:var(--color-border,#ddd);border-radius:2px;height:8px;overflow:hidden">'
                + '<div style="height:100%;background:var(--color-primary,#4e79a7);width:' + Math.min(100, pct) + '%"></div></div>'
                + '<span style="font-size:.74rem;white-space:nowrap;color:var(--color-text-muted)">' + pctTxt + '</span></div>';
        return '<tr>'
            + '<td>' + r.inst_id + '</td>'
            + '<td><code>' + r.sid + ',' + r.serial_num + '</code></td>'
            + '<td>' + escapeHtml(r.username || '—') + '</td>'
            + '<td>' + sqlIdCell(r.sql_id) + '</td>'
            + '<td>' + escapeHtml(r.opname || '—') + '</td>'
            + '<td>' + escapeHtml(r.target || '—') + '</td>'
            + '<td>' + bar + '</td>'
            + '<td>' + escapeHtml(fmtDateTime(r.start_time)) + '</td>'
            + '<td>' + escapeHtml(fmtDateTime(r.estimated_end)) + '</td>'
            + killBtnCell()
            + '</tr>';
    }).join('');
}




/* ── Toast ────────────────────────────────────────────────────────────────── */
function showToast(msg, kind) {
    var t = document.createElement('div');
    t.textContent = msg;
    t.style.cssText =
        'position:fixed;bottom:20px;right:20px;z-index:9100;'
        + 'padding:.6rem 1rem;border-radius:4px;font-size:.85rem;'
        + 'box-shadow:0 4px 12px rgba(0,0,0,.2);'
        + 'background:' + (kind === 'success' ? '#27ae60' : '#c0392b') + ';color:#fff;';
    document.body.appendChild(t);
    setTimeout(function () { t.remove(); }, 4000);
}

/* ── Data fetch ───────────────────────────────────────────────────────────── */
function fetchData() {
    fetch(BASE_URL + '&format=json', { credentials: 'same-origin' })
        .then(function (r) { return r.json(); })
        .then(function (data) {
            var errBox = document.getElementById('sess-active-error');
            if (data.error) {
                errBox.style.display = 'block';
                errBox.textContent = data.error;
                return;
            }
            errBox.style.display = 'none';
            var el = document.getElementById('sess-updated');
            if (el) el.textContent = data.updated || '—';
            renderSessions(data.sessions || []);
            renderLongOps(data.longops  || []);
        })
        .catch(function (e) { console.error('sess fetch:', e); });
}

/* ── Auto-refresh (10s) ───────────────────────────────────────────────────── */
function startRefresh() {
    if (_refreshTimer) clearInterval(_refreshTimer);
    if (_tickTimer)    clearInterval(_tickTimer);
    _cd = 10;
    _refreshTimer = setInterval(function () { _cd = 10; fetchData(); }, 10000);
    _tickTimer    = setInterval(function () {
        _cd = Math.max(0, _cd - 1);
        var el = document.getElementById('sess-countdown');
        if (el) el.textContent = _cd;
    }, 1000);
}

/* ── Boot ────────────────────────────────────────────────────────────────── */
fetchData();
startRefresh();

})();
