// FILE: _St/IG_StYellow/test_ext_auto_v262_exact_restore_v279c.js | ROLE: v262 자동 MP4·JPG WS8771 직접 다운로드 exact 복원 회귀 검사
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const vm = require('vm');

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

assert.strictEqual(manifest.version, '2.3.8.3070');
assert.strictEqual(manifest.version_name, '2.3.8.307');
assert.ok(side.includes('const IGBLUE_PACKAGE_VERSION = IGBLUE_BUILD_TAG;'));

function block(startToken, endToken) {
  const start = side.indexOf(startToken);
  const end = side.indexOf(endToken, start + startToken.length);
  assert.ok(start >= 0 && end > start, `block missing: ${startToken}`);
  return side.slice(start, end);
}

const kindsBlock = block(
  'function teAutoPyDownloadableKindsFromCache(media)',
  'function teAutoPyCacheTargetForMedia(media, rankNo)'
);
assert.ok(kindsBlock.includes('String(m.video_url || "").trim()'));
assert.ok(kindsBlock.includes('String(m.img_origin || m.img_large || m.img_small || m.img_b64 || "").trim()'));
assert.ok(!kindsBlock.includes('teDownloadVideoSave'));
assert.ok(!kindsBlock.includes('teDownloadImageSave'));
assert.ok(!kindsBlock.includes('metadata'));

const sandbox = {};
vm.createContext(sandbox);
vm.runInContext(`${kindsBlock}; this.kinds = teAutoPyDownloadableKindsFromCache;`, sandbox);
assert.deepStrictEqual(Array.from(sandbox.kinds({
  code: 'AUTO001',
  video_url: 'https://cdn.example/AUTO001.mp4',
  img_origin: 'https://cdn.example/AUTO001.jpg'
})), ['mp4', 'jpg']);
assert.deepStrictEqual(Array.from(sandbox.kinds({code: 'AUTO002'})), []);

const cachePairBlock = block(
  'async function teAutoPyDownloadMediaPairFromCache(media, rankNo, cycleBase, reason)',
  'async function teAutoPyTryCacheDownloadForRank(rankNo, list, ctx, cycleBase, reason)'
);
assert.ok(cachePairBlock.includes('for (const kind of ["mp4", "jpg"])'));
assert.ok(cachePairBlock.includes('teAutoPyDirectDownloadAsset(kind, m, collectMeta, base'));
assert.ok(!cachePairBlock.includes('"metadata"'));
assert.ok(!cachePairBlock.includes('teCollectMetadataOnlyEntry'));

const directAssetBlock = block(
  'async function teAutoPyDirectDownloadAsset(mediaType, currentMedia, collectMeta, cycleBase, extraMeta = {})',
  'async function teAutoPyDownloadMediaPairDirect(currentMedia, target, rankNo, cycleBase)'
);
assert.ok(directAssetBlock.includes('type: "IGBLUE_DOWNLOAD_URL"'));
assert.ok(directAssetBlock.includes('notify_aiwk: true'));
assert.ok(directAssetBlock.includes('auto_direct_download: true'));
assert.ok(directAssetBlock.includes('action: "ws8771_direct_download"'));
assert.ok(!directAssetBlock.includes('teDownloadStatusFlags('));

const directPairBlock = block(
  'async function teAutoPyDownloadMediaPairDirect(currentMedia, target, rankNo, cycleBase)',
  'async function teAutoPyStopCycle(stage, base, code, detail, extra)'
);
assert.ok(directPairBlock.includes('for (const kind of ["mp4", "jpg"])'));
assert.ok(directPairBlock.includes('(completed.length > 0 || alreadySaved.length > 0)'));
assert.ok(!directPairBlock.includes('metadataDone'));
assert.ok(!directPairBlock.includes('metadata_collected_done'));
assert.ok(!directPairBlock.includes('teCollectMetadataOnlyEntry'));

// metadata 수집 기능은 수동·통계 경로에만 유지한다.
assert.ok(side.includes('async function teCollectMetadataOnlyEntry(entry)'));
assert.ok(side.includes('ig_media_metadata_collect'));

// v279b 상태 보존과 v279aaaa Side 계정 클릭 선택은 유지한다.
assert.ok(side.includes('teProgressPreserveUntilNextDownload(newSession ? "auto_start_new_run" : "auto_account_continue")'));
assert.ok(side.includes('IG 계정 선택'));

console.log('test_ext_auto_v262_exact_restore_v279c: OK');
