import json
import subprocess
from pathlib import Path


LOADER = Path(__file__).parents[1] / "frontend" / "feature-loader.js"


def run_loader(scenario: str) -> dict:
    harness = f"""
const fs=require('fs'); const vm=require('vm');
const state={{appends:0, removed:0}};
const document={{
  head:{{appendChild(node){{ state.appends++; state.node=node; }} }},
  createElement(){{ return {{remove(){{state.removed++;}}}}; }},
}};
const context={{document, setTimeout, clearTimeout, console}};
context.globalThis=context;
vm.createContext(context);
vm.runInContext(fs.readFileSync({json.dumps(str(LOADER))},'utf8'),context);
const createFeatureLoader=context.createFeatureLoader;
(async()=>{{ {scenario} }})().catch(error=>{{console.error(error);process.exit(1);}});
"""
    completed = subprocess.run(["node", "-e", harness], check=True, capture_output=True, text=True)
    return json.loads(completed.stdout)


def test_concurrent_feature_requests_share_one_script():
    result = run_loader("""
const loader=createFeatureLoader({document, urls:{'issue-capture':'feature-a.js'}, timeoutMs:100});
const first=loader.load('issue-capture'); const second=loader.load('issue-capture');
state.node.onload(); await Promise.all([first,second]);
console.log(JSON.stringify({appends:state.appends,same:first===second,ready:loader.ready('issue-capture')}));
""")
    assert result == {"appends": 1, "same": True, "ready": True}


def test_failed_feature_request_can_retry_without_reload():
    result = run_loader("""
const loader=createFeatureLoader({document, urls:{'issue-capture':'feature-a.js'}, timeoutMs:100});
const failed=loader.load('issue-capture').catch(error=>error.message); state.node.onerror();
const message=await failed; const retry=loader.load('issue-capture'); state.node.onload(); await retry;
console.log(JSON.stringify({appends:state.appends,removed:state.removed,message,ready:loader.ready('issue-capture')}));
""")
    assert result == {"appends": 2, "removed": 1, "message": "Could not load issue capture.", "ready": True}


def test_feature_gate_exposes_loading_failure_and_success_to_mobile_controls():
    result = run_loader("""
const trigger={disabled:false}; const status={textContent:''}; let opened=0;
const loader=createFeatureLoader({document, urls:{'issue-capture':'feature-a.js'}, timeoutMs:100});
const failed=loader.run('issue-capture',{trigger,status},()=>{opened++;});
const loading={disabled:trigger.disabled,status:status.textContent}; state.node.onerror();
const first=await failed;
const failedState={disabled:trigger.disabled,status:status.textContent,opened};
const retry=loader.run('issue-capture',{trigger,status},()=>{opened++;}); state.node.onload();
const second=await retry;
console.log(JSON.stringify({loading,failedState,first,second,opened,finalStatus:status.textContent}));
""")
    assert result == {
        "loading": {"disabled": True, "status": "Loading issue capture…"},
        "failedState": {
            "disabled": False,
            "status": "Issue capture could not load. Tap New issue to retry.",
            "opened": 0,
        },
        "first": False,
        "second": True,
        "opened": 1,
        "finalStatus": "",
    }


def test_pull_workspace_failure_is_accessible_and_retryable_from_same_card():
    result = run_loader("""
const trigger={disabled:false}; const status={textContent:''}; let opened=0;
const loader=createFeatureLoader({document, urls:{'pull-workflow':'feature-pull.js'}, timeoutMs:100});
const failed=loader.run('pull-workflow',{trigger,status,retryLabel:'Tap the work card to retry.'},()=>{opened++;});
state.node.onerror(); const first=await failed;
const failedStatus=status.textContent;
const retry=loader.run('pull-workflow',{trigger,status,retryLabel:'Tap the work card to retry.'},()=>{opened++;});
state.node.onload(); const second=await retry;
console.log(JSON.stringify({first,second,failedStatus,opened,appends:state.appends}));
""")
    assert result == {
        "first": False,
        "second": True,
        "failedStatus": "Pull workspace could not load. Tap the work card to retry.",
        "opened": 1,
        "appends": 2,
    }


def test_security_center_failure_is_accessible_and_retryable_from_active_devices():
    result = run_loader("""
const trigger={disabled:false}; const status={textContent:''}; let opened=0;
const loader=createFeatureLoader({document, urls:{'security-center':'feature-security.js'}, timeoutMs:100});
const failed=loader.run('security-center',{trigger,status,retryLabel:'Tap Active devices to retry.'},()=>{opened++;});
state.node.onerror(); const first=await failed; const failedStatus=status.textContent;
const retry=loader.run('security-center',{trigger,status,retryLabel:'Tap Active devices to retry.'},()=>{opened++;});
state.node.onload(); const second=await retry;
console.log(JSON.stringify({first,second,failedStatus,opened,appends:state.appends}));
""")
    assert result == {
        "first": False,
        "second": True,
        "failedStatus": "Security center could not load. Tap Active devices to retry.",
        "opened": 1,
        "appends": 2,
    }
