// FILE: _St/IG_StYellow/test_ext_tab_control_v280.js | ROLE: v280 OWNER 인계·최근 탭 이력·Main 진단 표시 회귀 검사
const assert = require('assert');
const fs = require('fs');
const path = require('path');

const root = __dirname;
const manifest = JSON.parse(fs.readFileSync(path.join(root, 'manifest.json'), 'utf8'));
const background = fs.readFileSync(path.join(root, 'background.js'), 'utf8');
const side = fs.readFileSync(path.join(root, 'side.js'), 'utf8');
const content = fs.readFileSync(path.join(root, 'content_instagram.js'), 'utf8');
const inject = fs.readFileSync(path.join(root, 'js', 'instagram_inject.js'), 'utf8');

assert.strictEqual(manifest.version, '2.3.8.3140');
assert.strictEqual(manifest.version_name, '2.3.8.314');
assert.ok(manifest.description.includes('two-phase Side acknowledgement'));

for (const token of [
  'YELLOW/tab_control_v280',
  'IGBLUE_TAB_CONTROL_HISTORY_LIMIT = 20',
  'function igblueGetTabControlSnapshot(callback)',
  'function igblueClaimTabOwner(tabId, meta, callback)',
  'function igbluePrepareTabHandoff(previousTab, replacementTabId, targetUrl, navigationMeta, readyResult)',
  'function igblueCommitTabHandoff(token, detail, callback)',
  'PENDING_SIDE_ACK',
  'OWNER_COMMITTED',
  'largest_tab_id_fallback',
  'same_run_generation_ready',
  'generation_ready',
  'function igblueTabControlLifecycleState(eventState, managedState)',
  'IGBLUE_GET_TAB_CONTROL_STATE',
  'IGBLUE_CLAIM_TAB_OWNER',
  'IGBLUE_COMMIT_TAB_HANDOFF',
]) assert.ok(background.includes(token), `missing tab control token: ${token}`);

const commitStart = background.indexOf('function igblueCommitTabHandoff');
const commitEnd = background.indexOf('\n\n  igblueRestoreTabControlState();', commitStart);
const commit = background.slice(commitStart, commitEnd);
const ownerSetAt = commit.indexOf('igblueTabControlState.owner_tab_id = replacementId;');
const closeAt = commit.indexOf('igblueClosePreviousTabAfterReplacement');
assert.ok(ownerSetAt >= 0 && closeAt > ownerSetAt, 'new OWNER must be committed before old tab close');
assert.ok(commit.includes('handoff_state = "OWNER_COMMITTED"'));

for (const token of [
  'async function teAutoPyCommitTabHandoff',
  'async function teAutoPyClaimTabOwner',
  '[YELLOW][TAB-HANDOFF][SIDE_COMMIT_REQUEST]',
  '[YELLOW][TAB-HANDOFF][SIDE_COMMIT_RESPONSE]',
  'teAutoPySessionTarget.generation',
  'type: "IGBLUE_COMMIT_TAB_HANDOFF"',
  'type: "IGBLUE_CLAIM_TAB_OWNER"',
]) assert.ok(side.includes(token), `missing Side owner token: ${token}`);

for (const token of [
  "'탭 제어 ' + IGBLUE_EXT_BUILD_TAG",
  'CDP:${cdp} · 탭 ${count} · OWNER tab',
  'OWNER tab_id:',
  '최근 탭 이력',
  'data-yellow-tab-control-state',
  'igblueTabControlDiagText()',
  "type:'IGBLUE_GET_TAB_CONTROL_STATE'",
  '#igblue_main_diag_toggle.is-handoff',
  '#igblue_main_diag_toggle.is-warning',
  'igblue_main_diag_minimize',
  'igblue_main_diag_expand',
  'igblue_main_diag_refresh',
  'igblue_main_diag_copy',
]) assert.ok(content.includes(token), `missing Main tab diagnostic token: ${token}`);
assert.ok(!content.includes("toggle.textContent = '⋮'"));
assert.ok(!content.includes("'원점 보정',\n      '원점찾기'"));

assert.ok(inject.includes('tab_control_version:String(window.IGBLUE_MAIN_VERSION||window.IGBLUE_CONTENT_VERSION||"unknown")'));
assert.ok(inject.includes('tab_control:tabControl'));
assert.ok(inject.includes('data-yellow-tab-control-state'));
assert.ok(inject.includes('data-yellow-main-injection-ready",marker'));

console.log('OK test_ext_tab_control_v280');
