from intelligence.base import *
import requests
import json
import base64


URLSEARCH = "https://www.filescan.io/api/reports/search"
URLDL = "https://www.filescan.io/api/files"


class FileScanIO(OnlineChecker):

    name = "FileScanIO"
    options = {
        "key": ("", "FileScanIO API key"),
    }


    def __session(self):
        session = self.preconfigured_session()  # automatically set options such as timeout or ssl_verify
        key = self.options.get("key")
        if not key:
            raise KeyError("No API key")
        session.headers.update({'accept': 'application/json', 'X-Api-Key': key})
        return session
    
    def check(self, analysis):
        detections = { }
        session = self.__session()
        response = session.get(URLSEARCH, params={
            "sha256": analysis.entropy.sha256,
            })
        if response.ok:
            data = response.json()
            if "message" in data:
                raise ValueError(data["message"])
            #print(json.dumps(data, indent=4))
            items = data.get("items", [])
            for item in items:
                sha256 = item.get("file", {}).get("sha256", "")
                if sha256 != analysis.entropy.sha256:
                    continue
                filename = item.get("file", {}).get("name", "???")
                verdict = item.get("verdict")
                if verdict is not None:
                    level = DetectionLevel.from_text(verdict)
                else:
                    level = DetectionLevel.UNKNOWN
                name = "+".join([tag.get("tag", {}).get("name", "???") for tag in item.get("tags", [])])
                detections[filename] = OnlineDetection(level, name)
            if not detections:
                return None
        elif response.status_code == 404:
            return None
        else:
            response.raise_for_status()
            return None

        url = "https://www.filescan.io/search-result?query={}".format(base64.b64encode(analysis.entropy.sha256.encode("ascii")).decode("ascii"))
        return OnlineResult(detections=detections, 
            url=url
        )


    def download(self, query):
        session = self.__session()
        response = session.get(f"{URLDL}/{query.lower()}")
        if response.ok:
            data = response.json()
            if data["type"] != "base64":
                raise ValueError("Invalid content encoding")
            return OnlineFile(
                url=f"",
                content=base64.b64decode(data["content"])
            )
        elif response.status_code in (404, 403):
            return None
        else:
            response.raise_for_status()
            return None
