import dataclasses
import datetime
import typing

from .host import Host
from .message import Message
from .status_statistics import StatusStatistics
from .vulnerability import Vulnerability
from .web_scan_status import WebScanStatus


@dataclasses.dataclass
class WebVulnerabilityScanner:
    vulns: typing.Optional[typing.List[Vulnerability]] = None
    status: typing.Optional[str] = None
    duration: typing.Optional[int] = None
    messages: typing.Optional[typing.List[Message]] = None
    progress: typing.Optional[int] = None
    web_scan_status: typing.Optional[WebScanStatus] = None
    status_statistics: typing.Optional[StatusStatistics] = None
    hosts: typing.Optional[typing.Dict[str, Host]] = None
    status: typing.Optional[str] = None
    abort_requested: typing.Optional[bool] = None
    start_date: typing.Optional[datetime.datetime] = None
    end_date: typing.Optional[datetime.datetime] = None
    end_deadline: typing.Optional[datetime.datetime] = None
    event_level: typing.Optional[int] = None
    build: typing.Optional[str] = None

    @classmethod
    def from_dict(cls, data: dict):
        data = data["main"]

        if data.get("vulns"):
            data["vulns"] = [Vulnerability.from_dict(x) for x in data["vulns"]]
        if data.get("messages"):
            data["messages"] = [Message.from_dict(x) for x in data["messages"]]
        if data.get("web_scan_status"):
            data["web_scan_status"] = WebScanStatus.from_dict(data["web_scan_status"])
        if data.get("status_statistics"):
            data["status_statistics"] = StatusStatistics.from_dict(
                data["status_statistics"]
            )
        if data.get("hosts"):
            data["hosts"] = {k: Host.from_dict(v) for k, v in data["hosts"].items()}
        if data.get("start_date"):
            data["start_date"] = datetime.datetime.fromisoformat(data["start_date"])
        if data.get("end_date"):
            data["end_date"] = datetime.datetime.fromisoformat(data["end_date"])
        if data.get("end_deadline"):
            data["end_deadline"] = datetime.datetime.fromisoformat(data["end_deadline"])

        return cls(**data)

    def to_json(self):
        data = dataclasses.asdict(self)
        if data["start_date"]:
            data["start_date"] = data["start_date"].isoformat()
        if data["end_date"]:
            data["end_date"] = data["end_date"].isoformat()
        if data["end_deadline"]:
            data["end_deadline"] = data["end_deadline"].isoformat()

        data = dict(filter(lambda x: x[1] is not None, data.items()))

        return {"main": data}
