// Copyright (c) 2026, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
let protobufRoot = null;
let containerData = null;
let filteredRules = [];
let filteredFiles = [];
let currentView = 'rules'; // 'rules' or 'files'
let currentSelectedRule = null;
let currentRulePagination = { classes: 100, methods: 100, fields: 100 };

// Lookup maps
let tables = {
    rules: new Map(),
    classes: new Map(),
    fields: new Map(),
    methods: new Map(),
    types: new Map(),
    protos: new Map(),
    typeLists: new Map(),
    origins: new Map(),
    jarOrigins: new Map(),
    keepConstraints: new Map(),
    files: new Map(), // filename -> { rules: [], totalRadius: 0, classes: 0, methods: 0, fields: 0 }
    methodRefs: new Map(),
    fieldRefs: new Map()
};

let constraintStats = {
    DONT_OBFUSCATE: { classes: new Set(), methods: new Set(), fields: new Set() },
    DONT_OPTIMIZE: { classes: new Set(), methods: new Set(), fields: new Set() },
    DONT_SHRINK: { classes: new Set(), methods: new Set(), fields: new Set() }
};

const dropZone = document.getElementById('drop-zone');
const fileInput = document.getElementById('file-input');
const ruleList = document.getElementById('rule-list');
const searchInput = document.getElementById('search-input');
const mainContent = document.getElementById('main-content');
const statsOverview = document.getElementById('stats-overview');

// Load Protobuf definition
protobuf.load("blastradius.proto", function(err, root) {
    if (err) {
        console.error("Error loading proto:", err);
        alert("Failed to load blastradius.proto.");
        return;
    }
    protobufRoot = root;
});

dropZone.addEventListener('click', () => fileInput.click());

dropZone.addEventListener('dragover', (e) => {
    e.preventDefault();
    dropZone.classList.add('hover');
});

dropZone.addEventListener('dragleave', () => {
    dropZone.classList.remove('hover');
});

dropZone.addEventListener('drop', (e) => {
    e.preventDefault();
    dropZone.classList.remove('hover');
    if (e.dataTransfer.files.length > 0) {
        handleFile(e.dataTransfer.files[0]);
    }
});

fileInput.addEventListener('change', (e) => {
    if (e.target.files.length > 0) {
        handleFile(e.target.files[0]);
    }
});

searchInput.addEventListener('input', (e) => {
    if (currentView === 'rules') {
        filterRules(e.target.value);
    } else if (currentView === 'unused') {
        filterUnusedRules(e.target.value);
    } else if (currentView === 'redundant') {
        filterRedundantRules(e.target.value);
    } else {
        filterFiles(e.target.value);
    }
});

function handleFile(file) {
    if (!protobufRoot) {
        alert("Protobuf definition not loaded yet.");
        return;
    }

    const reader = new FileReader();
    reader.onload = function(e) {
        const arrayBuffer = e.target.result;
        try {
            const BlastRadiusContainer = protobufRoot.lookupType("com.android.tools.r8.blastradius.proto.BlastRadiusContainer");
            const buffer = new Uint8Array(arrayBuffer);
            const message = BlastRadiusContainer.decode(buffer);
            containerData = BlastRadiusContainer.toObject(message, {
                longs: String,
                enums: String,
                bytes: String,
                defaults: true,
                arrays: true,
                objects: true,
                oneofs: true
            });
            processData();
        } catch (err) {
            console.error("Error decoding proto:", err);
            alert("Failed to decode the .pb file. Ensure it matches the blastradius.proto schema.");
        }
    };
    reader.readAsArrayBuffer(file);
}

function processData() {
    // Clear previous data
    Object.values(tables).forEach(map => map instanceof Map ? map.clear() : null);
    tables.files = new Map();

    // Reset constraint stats
    Object.values(constraintStats).forEach(s => {
        s.classes.clear();
        s.methods.clear();
        s.fields.clear();
    });

    // Build lookup tables for origins
    if (containerData.classFileInJarOriginTable)
        containerData.classFileInJarOriginTable.forEach(o => tables.jarOrigins.set(o.id, o));
    if (containerData.fileOriginTable)
        containerData.fileOriginTable.forEach(o => tables.origins.set(o.id, o));

    // Build lookup table for references.
    if (containerData.fieldReferenceTable)
        containerData.fieldReferenceTable.forEach(f => tables.fieldRefs.set(f.id, f));
    if (containerData.methodReferenceTable)
        containerData.methodReferenceTable.forEach(m => tables.methodRefs.set(m.id, m));
    if (containerData.protoReferenceTable)
        containerData.protoReferenceTable.forEach(p => tables.protos.set(p.id, p));
    if (containerData.typeReferenceTable)
        containerData.typeReferenceTable.forEach(t => tables.types.set(t.id, t));
    if (containerData.typeReferenceListTable)
        containerData.typeReferenceListTable.forEach(tl => tables.typeLists.set(tl.id, tl));

    // Build lookup tables for kept items
    if (containerData.keptClassInfoTable)
        containerData.keptClassInfoTable.forEach(c => tables.classes.set(c.id, c));
    if (containerData.keptFieldInfoTable)
        containerData.keptFieldInfoTable.forEach(f => tables.fields.set(f.id, f));
    if (containerData.keptMethodInfoTable)
        containerData.keptMethodInfoTable.forEach(m => tables.methods.set(m.id, m));

    if (containerData.keepConstraintsTable)
        containerData.keepConstraintsTable.forEach(c => tables.keepConstraints.set(c.id, c));

    if (containerData.keepRuleBlastRadiusTable) {
        containerData.keepRuleBlastRadiusTable.forEach(r => {
            tables.rules.set(r.id, r);
            r.totalRadius = (r.blastRadius.classBlastRadius?.length || 0) +
                           (r.blastRadius.fieldBlastRadius?.length || 0) +
                           (r.blastRadius.methodBlastRadius?.length || 0);

            // Populate constraint stats
            const constraints = tables.keepConstraints.get(r.constraintsId);
            if (constraints && constraints.constraints) {
                constraints.constraints.forEach(c => {
                    const stats = constraintStats[c];
                    if (stats) {
                        r.blastRadius.classBlastRadius?.forEach(id => stats.classes.add(id));
                        r.blastRadius.methodBlastRadius?.forEach(id => stats.methods.add(id));
                        r.blastRadius.fieldBlastRadius?.forEach(id => stats.fields.add(id));
                    }
                });
            }

            // Group by file
            const fileName = getFileName(r.origin);
            if (!tables.files.has(fileName)) {
                tables.files.set(fileName, {
                    name: fileName,
                    rules: [],
                    classIds: new Set(),
                    methodIds: new Set(),
                    fieldIds: new Set()
                });
            }
            const fileData = tables.files.get(fileName);
            fileData.rules.push(r);
            r.blastRadius.classBlastRadius?.forEach(id => fileData.classIds.add(id));
            r.blastRadius.methodBlastRadius?.forEach(id => fileData.methodIds.add(id));
            r.blastRadius.fieldBlastRadius?.forEach(id => fileData.fieldIds.add(id));
        });

        // Compute final counts for files
        tables.files.forEach(fileData => {
            fileData.classes = fileData.classIds.size;
            fileData.methods = fileData.methodIds.size;
            fileData.fields = fileData.fieldIds.size;
            fileData.totalRadius = fileData.classes + fileData.methods + fileData.fields;
        });
    }

    renderStats();
    if (currentView === 'rules') {
        filterRules("");
    } else if (currentView === 'unused') {
        filterUnusedRules("");
    } else if (currentView === 'redundant') {
        filterRedundantRules("");
    } else {
        filterFiles("");
    }

    dropZone.classList.add('hidden');
    statsOverview.classList.remove('hidden');
    document.querySelector('.search-box').classList.remove('hidden');
    document.getElementById('welcome-message').classList.add('hidden');
}

function renderStats() {
    const rules = containerData.keepRuleBlastRadiusTable || [];
    const unusedCount = rules.filter(r => r.totalRadius === 0).length;
    const redundantCount = rules.filter(r => r.blastRadius.subsumedBy && r.blastRadius.subsumedBy.length > 0).length;

    const format = (val) => (val || 0).toLocaleString();

    document.getElementById('stat-rules').textContent = format(rules.length);

    // Constraint-specific counts
    document.getElementById('stat-no-obfuscation-classes').textContent = format(constraintStats.DONT_OBFUSCATE.classes.size);
    document.getElementById('stat-no-obfuscation-methods').textContent = format(constraintStats.DONT_OBFUSCATE.methods.size);
    document.getElementById('stat-no-obfuscation-fields').textContent = format(constraintStats.DONT_OBFUSCATE.fields.size);

    document.getElementById('stat-no-optimization-classes').textContent = format(constraintStats.DONT_OPTIMIZE.classes.size);
    document.getElementById('stat-no-optimization-methods').textContent = format(constraintStats.DONT_OPTIMIZE.methods.size);
    document.getElementById('stat-no-optimization-fields').textContent = format(constraintStats.DONT_OPTIMIZE.fields.size);

    document.getElementById('stat-no-shrinking-classes').textContent = format(constraintStats.DONT_SHRINK.classes.size);
    document.getElementById('stat-no-shrinking-methods').textContent = format(constraintStats.DONT_SHRINK.methods.size);
    document.getElementById('stat-no-shrinking-fields').textContent = format(constraintStats.DONT_SHRINK.fields.size);

    if (containerData.buildInfo) {
        const info = containerData.buildInfo;
        // Reachable counts
        document.getElementById('stat-reachable-classes').textContent = format(info.liveClassCount);
        document.getElementById('stat-reachable-methods').textContent = format(info.liveMethodCount);
        document.getElementById('stat-reachable-fields').textContent = format(info.liveFieldCount);
        // Total counts
        document.getElementById('stat-total-classes').textContent = format(info.classCount);
        document.getElementById('stat-total-methods').textContent = format(info.methodCount);
        document.getElementById('stat-total-fields').textContent = format(info.fieldCount);
    } else {
        // Fallback if buildInfo is missing
        document.getElementById('stat-reachable-classes').textContent = "-";
        document.getElementById('stat-reachable-methods').textContent = "-";
        document.getElementById('stat-reachable-fields').textContent = "-";
        document.getElementById('stat-total-classes').textContent = "-";
        document.getElementById('stat-total-methods').textContent = "-";
        document.getElementById('stat-total-fields').textContent = "-";
    }

    const unusedBadge = document.getElementById('unused-count');
    unusedBadge.textContent = unusedCount;
    unusedBadge.classList.remove('hidden');

    const redundantBadge = document.getElementById('redundant-count');
    redundantBadge.textContent = redundantCount;
    redundantBadge.classList.remove('hidden');
}

function filterRules(query) {
    const rules = containerData.keepRuleBlastRadiusTable || [];
    const lowerQuery = query.toLowerCase();

    filteredRules = rules.filter(r =>
        r.source.toLowerCase().includes(lowerQuery)
    );

    filteredRules.sort((a, b) => b.totalRadius - a.totalRadius);
    renderRuleList();
}

function filterFiles(query) {
    const files = Array.from(tables.files.values());
    const lowerQuery = query.toLowerCase();

    filteredFiles = files.filter(f =>
        f.name.toLowerCase().includes(lowerQuery)
    );

    filteredFiles.sort((a, b) => b.totalRadius - a.totalRadius);
    renderFileList();
}

function renderRuleList() {
    ruleList.innerHTML = '';
    filteredRules.forEach(rule => {
        const isRedundant = rule.blastRadius.subsumedBy && rule.blastRadius.subsumedBy.length > 0;
        let sameOriginSubsumption = false;
        if (isRedundant) {
            const ruleOriginFile = getFileName(rule.origin);
            sameOriginSubsumption = rule.blastRadius.subsumedBy.some(id => {
                const subsumer = tables.rules.get(id);
                return subsumer && getFileName(subsumer.origin) === ruleOriginFile;
            });
        }

        const div = document.createElement('div');
        div.className = 'rule-item';
        div.innerHTML = `
            <div style="display: flex; align-items: flex-start; gap: 8px;">
                ${sameOriginSubsumption ? '<span title="Subsumed by rule in same file" style="color: #ff9800; cursor: help;">⚠️</span>' : ''}
                <div style="flex: 1;">
                    <span class="rule-name">${escapeHtml(rule.source)}</span>
                    <div class="rule-stats">
                        Blast radius: ${rule.totalRadius}
                        (${rule.blastRadius.classBlastRadius?.length || 0} classes,
                         ${rule.blastRadius.methodBlastRadius?.length || 0} methods,
                         ${rule.blastRadius.fieldBlastRadius?.length || 0} fields)
                    </div>
                </div>
            </div>
        `;
        div.onclick = () => selectRule(rule, div);
        ruleList.appendChild(div);
    });
}

function renderFileList() {
    ruleList.innerHTML = '';
    filteredFiles.forEach(file => {
        const div = document.createElement('div');
        div.className = 'rule-item';
        div.innerHTML = `
            <span class="rule-name">${escapeHtml(file.name)}</span>
            <div class="rule-stats">
                Total radius: ${file.totalRadius} across ${file.rules.length} rules
                <br>(${file.classes} classes, ${file.methods} methods, ${file.fields} fields)
            </div>
        `;
        div.onclick = () => selectFile(file, div);
        ruleList.appendChild(div);
    });
}

function selectRule(rule, element) {
    document.querySelectorAll('.rule-item').forEach(el => el.classList.remove('active'));
    element.classList.add('active');
    currentSelectedRule = rule;
    currentRulePagination = { classes: 100, methods: 100, fields: 100 };
    renderRuleDetail(rule);
}

function selectFile(file, element) {
    document.querySelectorAll('.rule-item').forEach(el => el.classList.remove('active'));
    element.classList.add('active');
    renderFileDetail(file);
}

function renderRuleDetail(rule) {
    const isRedundant = rule.blastRadius.subsumedBy && rule.blastRadius.subsumedBy.length > 0;
    const ruleOriginFile = getFileName(rule.origin);

    let html = `
        <div class="card">
            <h2>Keep Rule Details</h2>
            ${isRedundant ? rule.blastRadius.subsumedBy.map(id => {
                const r = tables.rules.get(id);
                const isSameFile = r && getFileName(r.origin) === ruleOriginFile;
                const originStr = r ? getOriginString(r.origin) : "Unknown origin";
                return `
                    <div class="banner banner-warning">
                        <strong>Redundant Rule:</strong> This rule is fully subsumed by ${isSameFile ? 'another rule in the same file' : 'a rule in a different file'}:
                        <div style="margin-top: 0.5rem;">
                            <div class="subsumed-by-item">
                                <div style="font-weight: 500;">${r ? escapeHtml(r.source) : `Rule ID: ${id}`}</div>
                                <div style="font-size: 0.8rem; color: #666; margin-top: 2px;">Origin: ${originStr}</div>
                            </div>
                        </div>
                    </div>
                `;
            }).join('') : ''}
            <div class="keep-rule-source">${escapeHtml(rule.source)}</div>
            <p><strong>Origin:</strong> ${getOriginString(rule.origin)}</p>
        </div>
    `;

    html += renderBlastRadiusItems(rule.blastRadius);
    mainContent.innerHTML = html;
}

function renderFileDetail(file) {
    let html = `
        <div class="card">
            <h2>File Details</h2>
            <p><strong>File:</strong> ${escapeHtml(file.name)}</p>
            <p><strong>Total Impact:</strong> ${file.totalRadius} items kept across ${file.rules.length} rules.</p>
        </div>
        <div class="card">
            <h2>Keep Rules in this File</h2>
            <div class="item-list">
                ${file.rules.sort((a,b) => b.totalRadius - a.totalRadius).map(r => `
                    <div style="padding: 1rem; border-bottom: 1px solid #eee;">
                        <div class="rule-name">${escapeHtml(r.source)}</div>
                        <div class="rule-stats">Blast radius: ${r.totalRadius}</div>
                    </div>
                `).join('')}
            </div>
        </div>
    `;
    mainContent.innerHTML = html;
}

function renderBlastRadiusItems(blastRadius) {
    let html = "";

    const renderSection = (title, items, type, formatter, badgeClass, limit) => {
        if (!items || items.length === 0) return "";
        const visibleItems = items.slice(0, limit);
        const hasMore = items.length > limit;

        return `
            <div class="card">
                <div class="section-title">${title} <span class="badge ${badgeClass}">${items.length}</span></div>
                <ul class="item-list">
                    ${visibleItems.map(id => {
                        const info = type === 'class' ? tables.classes.get(id) :
                                   (type === 'method' ? tables.methods.get(id) : tables.fields.get(id));
                        return info ? `<li>${formatter(type === 'class' ? info.classReferenceId :
                                                     (type === 'method' ? info.methodReferenceId : info.fieldReferenceId))}</li>`
                                    : `<li>Unknown ${type} ID ${id}</li>`;
                    }).join('')}
                </ul>
                ${hasMore ? `<button class="show-more-btn" onclick="showMore('${type}')">Show more (${items.length - limit} remaining)</button>` : ''}
            </div>
        `;
    };

    html += renderSection("Matched Classes", blastRadius.classBlastRadius, 'class', formatTypeName, 'badge-green', currentRulePagination.classes);
    html += renderSection("Matched Methods", blastRadius.methodBlastRadius, 'method', formatMethodName, 'badge-blue', currentRulePagination.methods);
    html += renderSection("Matched Fields", blastRadius.fieldBlastRadius, 'field', formatFieldName, 'badge-red', currentRulePagination.fields);

    return html;
}

function showMore(type) {
    if (type === 'class') currentRulePagination.classes += 100;
    else if (type === 'method') currentRulePagination.methods += 100;
    else if (type === 'field') currentRulePagination.fields += 100;

    if (currentSelectedRule) {
        renderRuleDetail(currentSelectedRule);
    }
}

function filterUnusedRules(query) {
    const rules = containerData.keepRuleBlastRadiusTable || [];
    const lowerQuery = query.toLowerCase();

    filteredRules = rules.filter(r =>
        r.totalRadius === 0 && r.source.toLowerCase().includes(lowerQuery)
    );

    // For unused rules, sort by source text
    filteredRules.sort((a, b) => a.source.localeCompare(b.source));
    renderRuleList();
}

function filterRedundantRules(query) {
    const rules = containerData.keepRuleBlastRadiusTable || [];
    const lowerQuery = query.toLowerCase();

    filteredRules = rules.filter(r =>
        r.blastRadius.subsumedBy && r.blastRadius.subsumedBy.length > 0 &&
        r.source.toLowerCase().includes(lowerQuery)
    );

    filteredRules.sort((a, b) => b.totalRadius - a.totalRadius);
    renderRuleList();
}

function switchView(view) {
    currentView = view;
    document.querySelectorAll('.tab-button').forEach(btn => {
        btn.classList.toggle('active', btn.getAttribute('onclick').includes(view));
    });

    searchInput.value = "";
    searchInput.placeholder = view === 'files' ? "Search files..." : "Search keep rules...";

    if (containerData) {
        if (view === 'rules') {
            filterRules("");
        } else if (view === 'unused') {
            filterUnusedRules("");
        } else if (view === 'redundant') {
            filterRedundantRules("");
        } else {
            filterFiles("");
        }
    }
    mainContent.innerHTML = '';
}

function formatTypeName(typeId) {
    const type = tables.types.get(typeId);
    if (!type) return "Unknown";
    return formatDescriptor(type.javaDescriptor);
}

function formatDescriptor(desc) {
    if (!desc) return "";
    let dimensions = 0;
    while (desc[dimensions] === '[') {
        dimensions++;
    }
    let base = desc.substring(dimensions);
    let res = "";
    if (base.startsWith('L') && base.endsWith(';')) {
        res = base.substring(1, base.length - 1).replace(/\//g, '.');
    } else if (base.length === 1) {
        switch (base[0]) {
            case 'V': res = "void"; break;
            case 'Z': res = "boolean"; break;
            case 'B': res = "byte"; break;
            case 'S': res = "short"; break;
            case 'C': res = "char"; break;
            case 'I': res = "int"; break;
            case 'J': res = "long"; break;
            case 'F': res = "float"; break;
            case 'D': res = "double"; break;
            default: res = base;
        }
    } else {
        res = base;
    }
    for (let i = 0; i < dimensions; i++) {
        res += "[]";
    }
    return res;
}

function formatMethodName(methodRefId) {
    const ref = tables.methodRefs.get(methodRefId);
    if (!ref) return "Unknown method";
    const className = formatTypeName(ref.classReferenceId);
    const proto = tables.protos.get(ref.protoReferenceId);
    let params = "";
    if (proto && proto.parametersId) {
        const list = tables.typeLists.get(proto.parametersId);
        if (list && list.typeReferenceIds) {
            params = list.typeReferenceIds.map(id => formatTypeName(id)).join(', ');
        }
    }
    const returnType = proto ? formatTypeName(proto.returnTypeId) : "";
    return `${returnType} ${className}.${ref.name}(${params})`;
}

function formatFieldName(fieldRefId) {
    const ref = tables.fieldRefs.get(fieldRefId);
    if (!ref) return "Unknown field";
    const className = formatTypeName(ref.classReferenceId);
    const type = formatTypeName(ref.typeReferenceId);
    return `${type} ${className}.${ref.name}`;
}

function getFileName(origin) {
    if (!origin) return "Unknown";
    const fileOrigin = tables.origins.get(origin.fileOriginId);
    return fileOrigin ? fileOrigin.filename : "Unknown";
}

function getOriginString(origin) {
    if (!origin) return "Unknown";
    const name = getFileName(origin);
    let res = name;
    if (origin.lineNumber) {
        res += ":" + origin.lineNumber;
        if (origin.columnNumber) res += ":" + origin.columnNumber;
    }
    return res;
}

function escapeHtml(text) {
    if (!text) return "";
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
}