// FILE: _St/IG_StYellow/test_ext_download_cache_recovery_v278.js | ROLE: IG_StYellow 회귀 테스트
const fs = require('fs');
const path = require('path');
const vm = require('vm');
const assert = require('assert');

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.3190');
assert.strictEqual(manifest.version_name, '2.3.8.319');
assert.ok(side.includes('const IGBLUE_PACKAGE_VERSION = IGBLUE_BUILD_TAG;'));

// v262에서 실제 확인된 snapshot/Side URL 직접 다운로드 경로를 자동 실행에서도 다시 허용한다.
assert.ok(side.includes('async function teAutoPyTryCacheDownloadForRank'));
assert.ok(!side.includes('allow_cache_fallback: false'));
assert.ok(side.includes('S00_PRELOAD_CACHE_FALLBACK_OK'));
assert.ok(side.includes('S04_CACHE_RECOVERY_ADVANCE'));
assert.ok(side.includes('snapshot_cache_recovery_complete'));
assert.ok(side.includes('teAutoPyFeatureCheck("AD-03-E01", "[예외추적]"'));
assert.ok(side.includes('teAutoPyFeatureCheck("AD-03", "[복구완료]"'));

// snapshot 복구는 요청 No·shortcode·owner·선택 자산 URL이 정확할 때만 허용한다.
const start = side.indexOf('function teAutoPyDownloadableKindsFromCache(media)');
const end = side.indexOf('async function teAutoPyDownloadMediaPairFromCache', start);
assert.ok(start >= 0 && end > start, 'snapshot recovery helper block missing');
let videoSave = true;
let imageSave = false;
const ctx = {
  Date,
  teMediaOwnerName: (m) => m.owner_username || m.username || '',
  teDownloadVideoSave: () => videoSave,
  teDownloadImageSave: () => imageSave
};
vm.createContext(ctx);
vm.runInContext(`${side.slice(start, end)};
this.checkRecovery=teAutoPySnapshotRecoveryCheck;
this.resolveTarget=teAutoPyResolveTargetForRank;`, ctx);

const videoSnapshot = {
  __igblue_auto_snapshot_no: 1,
  __igblue_auto_snapshot_shortcode: 'GOOD001',
  code: 'GOOD001',
  owner_username: 'good_account',
  video_url: 'https://cdn.example/GOOD001.mp4',
  img_origin: 'https://cdn.example/GOOD001.jpg'
};
let check = ctx.checkRecovery({}, videoSnapshot, 1);
assert.strictEqual(check.ok, true);
assert.strictEqual(check.actual_conflict, false);
assert.deepStrictEqual(Array.from(check.downloadable_kinds), ['mp4']);
let resolved = ctx.resolveTarget({}, videoSnapshot, 1);
assert.strictEqual(resolved.recovered, true);
assert.strictEqual(resolved.source, 'auto_snapshot_rank_target');
assert.strictEqual(resolved.target.code, 'GOOD001');

// Main이 동일 shortcode를 주면 Main 대상 그대로 사용한다.
resolved = ctx.resolveTarget({rank:1, code:'GOOD001', owner_username:'good_account'}, videoSnapshot, 1);
assert.strictEqual(resolved.recovered, false);
assert.strictEqual(resolved.source, 'main_active_target');

// Main이 다른 실제 shortcode를 주면 snapshot으로 무마하지 않고 중단 대상으로 남긴다.
check = ctx.checkRecovery({rank:1, code:'OTHER999'}, videoSnapshot, 1);
assert.strictEqual(check.ok, false);
assert.strictEqual(check.actual_conflict, true);
resolved = ctx.resolveTarget({rank:1, code:'OTHER999'}, videoSnapshot, 1);
assert.strictEqual(resolved.recovered, false);
assert.strictEqual(resolved.conflict, true);
assert.strictEqual(resolved.source, 'main_active_conflict');

// owner 또는 정확한 snapshot No가 없으면 복구 다운로드를 허용하지 않는다.
assert.strictEqual(ctx.checkRecovery({}, {...videoSnapshot, owner_username:'', username:''}, 1).ok, false);
assert.strictEqual(ctx.checkRecovery({}, {...videoSnapshot, __igblue_auto_snapshot_no:2}, 1).ok, false);

// v313 일반 JPG 파일 저장은 Cache8701이 담당하므로 video 저장도 꺼지면 파일 다운로드 복구 대상이 없다.
videoSave = false;
imageSave = false;
check = ctx.checkRecovery({}, videoSnapshot, 1);
assert.strictEqual(check.ok, false);
assert.deepStrictEqual(Array.from(check.downloadable_kinds), []);

// 기존 수동 다운로드 시작 경로는 변경하지 않는다.
for (const token of [
  'function teNotifyManualDownloadStart(media, assetKind, mediaIndex = 0, meta = null)',
  'source_mode: "MANUAL_SINGLE"',
  'message: "수동 다운로드 시작"',
  'teSendToTargetTab(payload, "").catch(() => {})'
]) assert.ok(side.includes(token), `manual download regression: ${token}`);

console.log('OK test_ext_download_cache_recovery_v278');
