import json
import subprocess
from pathlib import Path


MODULE = Path(__file__).resolve().parents[1] / "frontend" / "shared-image-capture.js"


def test_shared_image_is_consumed_once_and_restored_into_capture():
    script = f"""
const shared = require({json.dumps(str(MODULE))});
const calls=[];
const store={{
  get:async id=>({{filename:'bug.png',contentType:'image/png',blob:{{size:6,type:'image/png'}}}}),
  delete:async id=>calls.push(['delete',id]),
}};
shared.consume({{
  marker:'image', store,
  restore:value=>calls.push(['restore',value.filename]),
  status:message=>calls.push(['status',message]),
}}).then(first=>shared.consume({{marker:'',store,restore:()=>calls.push(['restore-again'])}}).then(second=>{{
  process.stdout.write(JSON.stringify({{first,second,calls}}));
}}));
"""
    completed = subprocess.run(["node", "-e", script], capture_output=True, text=True)

    assert completed.returncode == 0, completed.stderr
    assert json.loads(completed.stdout) == {
        "first": True,
        "second": False,
        "calls": [
            ["restore", "bug.png"],
            ["delete", "shared-image"],
            ["status", "Shared screenshot ready to file with this issue."],
        ],
    }


def test_shared_evidence_bundle_is_consumed_once_in_order():
    script = f"""
const shared=require({json.dumps(str(MODULE))});const calls=[];
const store={{get:async()=>({{attachments:[
  {{filename:'one.png',contentType:'image/png',blob:new Blob(['one'],{{type:'image/png'}})}},
  {{filename:'two.jpg',contentType:'image/jpeg',blob:new Blob(['two'],{{type:'image/jpeg'}})}},
]}}),delete:async id=>calls.push(['delete',id])}};
(async()=>{{const result=await shared.consume({{marker:'images',store,restore:value=>calls.push(['restore',value.map(x=>x.filename)]),status:value=>calls.push(['status',value])}});process.stdout.write(JSON.stringify({{result,calls}}));}})();
"""
    output = json.loads(subprocess.run(["node", "-e", script], check=True, capture_output=True, text=True).stdout)
    assert output == {"result": True, "calls": [
        ["restore", ["one.png", "two.jpg"]], ["delete", "shared-image"],
        ["status", "2 shared screenshots ready to file with this issue."],
    ]}



def test_invalid_shared_image_reports_error_without_touching_open_capture():
    script = f"""
const shared = require({json.dumps(str(MODULE))});
const calls=[];
shared.consume({{
  marker:'unsupported', store:{{get:async()=>null,delete:async()=>calls.push('delete')}},
  restore:()=>calls.push('restore'), status:message=>calls.push(message),
}}).then(result=>process.stdout.write(JSON.stringify({{result,calls}})));
"""
    completed = subprocess.run(["node", "-e", script], capture_output=True, text=True)

    assert completed.returncode == 0, completed.stderr
    assert json.loads(completed.stdout) == {
        "result": False,
        "calls": ["Share one PNG, JPEG, or WebP screenshot."],
    }


def test_private_share_bundle_restores_metadata_and_ordered_images_once():
    script = f"""
const shared=require({json.dumps(str(MODULE))});const calls=[];
const store={{get:async()=>({{
  title:'Broken checkout',text:'Steps to reproduce',url:'https://example.test/private',
  attachments:[{{filename:'one.png',contentType:'image/png',blob:new Blob(['one'],{{type:'image/png'}})}}],
}}),delete:async id=>calls.push(['delete',id])}};
(async()=>{{const result=await shared.consume({{
  marker:'bundle',store,
  restore:value=>calls.push(['restore',value.map(x=>x.filename)]),
  restoreContent:value=>calls.push(['content',value]),
  status:value=>calls.push(['status',value]),
}});process.stdout.write(JSON.stringify({{result,calls}}));}})();
"""
    output = json.loads(subprocess.run(["node", "-e", script], check=True, capture_output=True, text=True).stdout)

    assert output == {"result": True, "calls": [
        ["content", {"title": "Broken checkout", "text": "Steps to reproduce", "url": "https://example.test/private"}],
        ["restore", ["one.png"]],
        ["delete", "shared-image"],
        ["status", "Shared content and screenshot ready to file with this issue."],
    ]}
