import gzip
import io
import tarfile
import zipfile
from pathlib import Path

from sentra.firmware import analyze_firmware


def test_analyze_firmware_extracts_zip_and_collects_analysis_signals(tmp_path: Path) -> None:
    firmware_path = tmp_path / "firmware.zip"
    with zipfile.ZipFile(firmware_path, "w") as archive:
        archive.writestr("etc/device.conf", "password=admin\nhost=broker.local\n")
        archive.writestr("www/index.html", "nginx camera")
        archive.writestr("certs/device.pem", "BEGIN CERTIFICATE\nCN=device.local\nEND CERTIFICATE\n")

    artifact = analyze_firmware(str(firmware_path), workspace=tmp_path)

    assert artifact.extracted_metadata["provider"] == "zip"
    assert artifact.extraction_metadata.provider == "zip"
    assert artifact.extraction_metadata.detected_type == "zip"
    assert len(artifact.extracted_artifacts) == 3
    assert artifact.config_hints
    assert artifact.certificates
    assert artifact.certificate_findings
    assert any(hint.service == "http" for hint in artifact.service_hints)
    assert any(component.normalized_name == "nginx" for component in artifact.software_components)
    assert artifact.component_evidence
    assert artifact.observed_facts
    assert artifact.inference_hints


def test_analyze_firmware_extracts_gzip_payload(tmp_path: Path) -> None:
    firmware_path = tmp_path / "firmware.txt.gz"
    with gzip.open(firmware_path, "wb") as stream:
        stream.write(b"northwind modbus mosquitto")

    artifact = analyze_firmware(str(firmware_path), workspace=tmp_path)

    assert artifact.extracted_metadata["provider"] == "gzip"
    assert artifact.extracted_artifacts[0].relative_path == "firmware.txt"
    assert any(hint.service == "modbus" for hint in artifact.service_hints)


def test_analyze_firmware_extracts_tar_payload(tmp_path: Path) -> None:
    firmware_path = tmp_path / "firmware.tar"
    payload = io.BytesIO()
    with tarfile.open(fileobj=payload, mode="w") as archive:
        content = b"dropbear sshd"
        info = tarfile.TarInfo("bin/dropbear.conf")
        info.size = len(content)
        archive.addfile(info, io.BytesIO(content))
    firmware_path.write_bytes(payload.getvalue())

    artifact = analyze_firmware(str(firmware_path), workspace=tmp_path)

    assert artifact.extracted_metadata["provider"] == "tar"
    assert any(component.normalized_name == "dropbear" for component in artifact.software_components)


def test_analyze_firmware_tracks_nested_archive_metadata(tmp_path: Path) -> None:
    inner_bytes = io.BytesIO()
    with zipfile.ZipFile(inner_bytes, "w") as inner:
        inner.writestr("etc/device.conf", "mqtt_port=1883\n")

    firmware_path = tmp_path / "nested.zip"
    with zipfile.ZipFile(firmware_path, "w") as archive:
        archive.writestr("inner.zip", inner_bytes.getvalue())

    artifact = analyze_firmware(str(firmware_path), workspace=tmp_path)

    assert artifact.extraction_metadata.nested_archives_seen == 1
    assert any(item.relative_path.endswith("inner/etc/device.conf") for item in artifact.extracted_artifacts)
    assert any(hint.service == "mqtt" for hint in artifact.service_hints)

