// 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');

const embeddedProtoSchemaSource = document.getElementById('blastradius-proto');
const embeddedProtoDataSource = document.getElementById('blastradius-data');

// Load Protobuf definition.
if (embeddedProtoSchemaSource) {
  try {
    protobufRoot = protobuf.parse(embeddedProtoSchemaSource.textContent).root;
  } catch (e) {
    console.error("Failed to parse embedded proto:", e);
  }
} else {
  protobuf.load("blastradius.proto", function(err, root) {
    if (err) {
      console.error("Error loading proto:", err);
      alert("Failed to load blastradius.proto.");
      return;
    }
    protobufRoot = root;
  });
}

// Load blast radius data (.pb).
if (embeddedProtoDataSource) {
  try {
    const binary = atob(embeddedProtoDataSource.textContent.trim());
    const bytes = new Uint8Array(binary.length);
    for (let i = 0; i < binary.length; i++) {
      bytes[i] = binary.charCodeAt(i);
    }
    const BlastRadiusContainer = protobufRoot.lookupType("com.android.tools.r8.blastradius.proto.BlastRadiusContainer");
    const message = BlastRadiusContainer.decode(bytes);
    containerData = BlastRadiusContainer.toObject(message, {
      longs: String,
      enums: String,
      bytes: String,
      defaults: true,
      arrays: true,
      objects: true,
      oneofs: true
    });
    processData();
  } catch (e) {
    console.error("Failed to decode embedded data:", e);
  }
} else {
  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]);
    }
  });

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

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 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,
          origin: r.origin,
          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(getOriginString(file.origin))}</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 getMavenCoordinate(origin) {
  if (!origin) return null;
  const fileOrigin = tables.origins.get(origin.fileOriginId);
  return fileOrigin?.mavenCoordinate;
}

function getMavenCoordinateString(mavenCoordinate) {
  return mavenCoordinate.groupId + ":" + mavenCoordinate.artifactId + ":" + mavenCoordinate.version;
}

function getOriginString(origin) {
  if (!origin) return "Unknown";
  const mavenCoordinate = getMavenCoordinate(origin);
  if (mavenCoordinate) {
    return getMavenCoordinateString(mavenCoordinate);
  }
  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;
}
