#!/usr/bin/env python
"""Module for the MalwareBazaar service"""

from typing import Optional

import requests
from backoff import expo, on_exception
from ratelimit import RateLimitException, limits

from ioccheck.services.service import Service


class MalwareBazaar(Service):
    """ Represents the data from a MalwareBazaar API response"""

    name = "malwarebazaar"
    url = "https://mb-api.abuse.ch/api/v1/"
    ioc: str

    def __init__(self, ioc: str, api_key: str):
        Service.__init__(self, ioc, api_key)
        self.response = self._get_api_response(self.ioc, api_key)
        self._response_data = self.response.get("data")[0]

        if self.response.get("query_status") == "hash_not_found":
            return

        self.is_malicious = None  # self._get_is_malicious(self.response)

    @on_exception(expo, RateLimitException, max_tries=10)
    @limits(calls=15, period=60)
    def _get_api_response(self, ioc: str, api_key: str) -> dict:
        return requests.post(
            self.url,
            data={"query": "get_info", "hash": ioc},
            headers={"API_KEY": api_key},
        ).json()

    @property
    def investigation_url(self) -> Optional[str]:
        """ The URL a human can use to follow up for more information """
        sha256_hash = self.hashes.get("sha256_hash")

        # MalwareBazaar indexes URLs by their SHA256 hash
        if sha256_hash is not None:
            return f"https://bazaar.abuse.ch/sample/{sha256_hash}/"

        return None

    @property
    def hashes(self) -> dict:
        """Other hashes for this file generated by other algorithms"""
        hash_keys = [
            "sha256_hash",
            "sha1_hash",
            "md5_hash",
            "sha3_384_hash",
            "imphash",
            "tlsh",
            "telfhash",
        ]

        return dict(
            (key, value)
            for key, value in self.response.get("data")[0].items()
            if key in hash_keys
        )

    @property
    def signature(self) -> Optional[str]:
        """The signature of the sample returned by MalwareBazaar"""
        return self._response_data.get("signature")

    @property
    def tags(self) -> Optional[list]:
        """User-submitted tags for the sample from the MalwareBazaar website"""
        return self._response_data.get("tags")

    @property
    def file_size(self) -> Optional[int]:
        """Returns the file size of the sample"""
        return self._response_data.get("file_size")

    @property
    def file_type(self) -> Optional[str]:
        """Returns the file extension of the sample"""
        return self._response_data.get("file_type")

    @property
    def mime_type(self) -> Optional[str]:
        """Returns the MIME type of the sample"""
        return self._response_data.get("file_type_mime")
