/**
 * Demo Oracle — arborescence des verrous (rafraichissement 10 s).
 * Lit sa configuration dans window.DemoOracleReport.realtimeLocks.
 *
 * Portage de modules/oracle/assets/js/report-realtime-locks.js, ampute de
 * l'arret de session — bouton, fenetre, POST — et du lien vers le detail SQL,
 * page qui n'existe pas dans la demonstration.
 */
(function () {
'use strict';

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

var BASE_URL   = config.baseUrl      || '';
var T          = config.T            || {};

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

function escapeHtml(s) {
    return String(s == null ? '' : s)
        .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;').replace(/'/g, '&#39;');
}
function fmtDuration(sec) {
    if (sec == null || sec < 0) return '—';
    var h = Math.floor(sec / 3600), m = Math.floor((sec % 3600) / 60), 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';
}

/* ── Build tree from flat list ──────────────────────────────────────────── */
function buildTree(sessions) {
    var byKey = {};
    sessions.forEach(function (s) {
        s._children = [];
        byKey[s.inst_id + ':' + s.sid] = s;
    });
    var roots = [];
    sessions.forEach(function (s) {
        if (s.blocking_instance !== null && s.blocking_session !== null) {
            var parent = byKey[s.blocking_instance + ':' + s.blocking_session];
            if (parent) { parent._children.push(s); return; }
        }
        roots.push(s);
    });
    return roots;
}


function sqlIdLink(sid) {
    if (!sid) return '<span style="color:var(--color-text-muted)">—</span>';
    var safe = escapeHtml(sid);
    return '<code style="user-select:all">'
         + '<code>' + safe + '</code></a>';
}

function renderNode(s, isRoot) {
    var badge, badgeBg;
    if (isRoot && s.holds_blocking_lock > 0) {
        badge = T.blocker || 'Blocker'; badgeBg = '#c0392b';
    } else if (isRoot) {
        badge = T.blocker || 'Blocker'; badgeBg = '#e67e22';
    } else {
        badge = T.blocked || 'Blocked'; badgeBg = '#3498db';
    }
    var html = ''
        + '<div style="border:1px solid var(--color-border);border-radius:6px;padding:.45rem .65rem;margin-bottom:.45rem;background:var(--color-surface)">'
        + '<div style="display:flex;align-items:center;gap:.5rem;flex-wrap:wrap">'
        +   '<span class="badge" style="background:' + badgeBg + ';color:#fff;font-size:.7rem;font-weight:700">'
        +     escapeHtml(badge) + '</span>'
        +   '<code style="font-weight:700">' + s.inst_id + ':' + s.sid + ',' + s.serial_num + '</code>'
        +   '<span style="font-size:.82rem">'
        +     '👤 ' + escapeHtml(s.username);
    if (s.schemaname && s.schemaname !== s.username) html += ' (' + escapeHtml(s.schemaname) + ')';
    html += '</span>';

    if (s.status) {
        html += '<span class="badge badge-info" style="font-size:.7rem">' + escapeHtml(s.status) + '</span>';
    }
    if (!isRoot && s.blocking_instance !== null) {
        html += '<span style="font-size:.78rem;color:var(--color-text-muted)">'
              + ' ' + escapeHtml(T.blocked_by || 'blocked by') + ' '
              + '<code>' + s.blocking_instance + ':' + s.blocking_session + '</code></span>';
    }
    if (s.holds_blocking_lock > 0 && isRoot) {
        html += '<span style="font-size:.72rem;color:#c0392b;font-weight:700"> 🔒 ' + escapeHtml(T.holds || 'holds blocking lock') + '</span>';
    }
    html += '</div>';

    // Details
    html += '<div style="margin-top:.35rem;font-size:.78rem;color:var(--color-text-muted);display:flex;flex-wrap:wrap;gap:.75rem 1.25rem">'
        +   '<span>📍 ' + escapeHtml(s.machine || '?') + ' / ' + escapeHtml(s.program || '?') + '</span>';
    if (s.module)  html += '<span>📦 ' + escapeHtml(s.module) + '</span>';
    if (s.osuser)  html += '<span>OS: ' + escapeHtml(s.osuser) + '</span>';
    html += '<span>' + escapeHtml(T.wait || 'Wait') + ' : <strong style="color:var(--color-text)">'
         + fmtDuration(s.seconds_in_wait) + '</strong></span>';
    if (s.wait_class) html += '<span>⏳ ' + escapeHtml(s.wait_class) + '</span>';
    if (s.event)      html += '<span style="font-family:monospace">' + escapeHtml(s.event) + '</span>';
    html += '</div>';

    if (s.sql_id || s.sql_preview) {
        html += '<div style="margin-top:.3rem;font-size:.78rem">'
              + 'SQL : ' + sqlIdLink(s.sql_id);
        if (s.sql_preview) {
            html += ' <code style="background:var(--color-input-bg,#f5f5f5);padding:.1rem .35rem;border-radius:3px">'
                  + escapeHtml(s.sql_preview) + '</code>';
        }
        html += '</div>';
    }

    if (s._children && s._children.length) {
        html += '<div style="margin-top:.45rem;margin-left:1.2rem;border-left:2px solid var(--color-border);padding-left:.8rem">';
        s._children.forEach(function (c) { html += renderNode(c, false); });
        html += '</div>';
    }
    html += '</div>';
    return html;
}

function renderTree(sessions) {
    var card  = document.getElementById('locks-tree-card');
    var empty = document.getElementById('locks-empty');
    var box   = document.getElementById('locks-tree');
    if (!sessions || !sessions.length) {
        if (card)  card.style.display  = 'none';
        if (empty) empty.style.display = '';
        if (box)   box.innerHTML       = '';
        return;
    }
    if (empty) empty.style.display = 'none';
    if (card)  card.style.display  = '';
    var roots = buildTree(sessions);
    box.innerHTML = roots.map(function (r) { return renderNode(r, true); }).join('');
}

/* ── Kill modal ──────────────────────────────────────────────────────────── */



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);
}

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

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('locks-countdown');
        if (el) el.textContent = _cd;
    }, 1000);
}

fetchData();
startRefresh();

})();
