from Managers.FileManager import FileManager
from Managers.DatabaseManager import DatabaseManager
from Entities.Response import Response
from Entities.Vulnerability import Vulnerability

class VulnerabilityManager():

    def __init__(self, db_manager = DatabaseManager()):
        self.file_manager = FileManager()
        self.db_manager = db_manager
        self.vulnerabilities_dict = self._initializeFromDatabase()

    def _initializeFromDatabase(self):
        """
        Pre-populates the database with vulnerabilities.
        :return: Dictionary containing scenario's data
        """
        # Variables
        vulnerabilities_dict = dict()
        vulnerabilities = self.db_manager.getVulnerabilities()
        for raw_vulnerability in vulnerabilities:
            del raw_vulnerability["_id"]
            vulnerability_name = raw_vulnerability["name"]
            vulnerability = Vulnerability().objectFromDictionary(raw_vulnerability)
            vulnerabilities_dict[vulnerability_name] = vulnerability
        return vulnerabilities_dict

    def newEmpty(self, vulnerability_name):
        """
        Creates a new vulnerability which includes the folders and the vulnerability JSON file
        :param vulnerability_name: String with the vulnerability name
        :return: Response object containing the status of the request
        """
        response = Response()
        if vulnerability_name not in self.vulnerabilities_dict:
            vulnerability = Vulnerability(vulnerability_name)
            self.vulnerabilities_dict[vulnerability_name] = vulnerability
            self.db_manager.insertVulnerability(vulnerability.dictionary().copy())
            response.setResponse(True)
            response.setBody(vulnerability.dictionary())
        else:
            response.setResponse(False)
            response.setReason('Vulnerability already exist')
            response.setBody(dict())
        return response.dictionary()

    def getAll(self):
        """
        Gets the available exploits
        :return: Response object containing the status of the request
        """
        # Variables
        vulnerabilities_dict = {"vulnerabilities": [self.vulnerabilities_dict[v].name for v in self.vulnerabilities_dict]}
        response = Response()
        response.setResponse(True)
        response.setBody(vulnerabilities_dict)
        return response.dictionary()


    def getOne(self, vulnerability_name):
        """
        Gets the scenario as a JSON file
        :param vulnerability_name: VUlnerability's name string
        :return: Response object containing the status of the request
        """
        response = Response()
        if vulnerability_name in self.vulnerabilities_dict:
            response.setResponse(True)
            response.setBody(self.vulnerabilities_dict[vulnerability_name].dictionary())
        else:
            response.setResponse(False)
            response.setReason('Vulnerability doesn\'t exist')
            response.setBody(dict())
        return response.dictionary()

    def editOne(self, vulnerability_json):
        """
        Edits a current scenario with a JSON file
        :param vulnerability_json: JSON file new vulnerability
        :return: Response object containing the status of the request
        """
        response = Response()
        print(vulnerability_json)
        vulnerability_name = vulnerability_json["name"]
        if vulnerability_name in self.vulnerabilities_dict:
            vulnerability_json = Vulnerability().objectFromDictionary(vulnerability_json)
            self.vulnerabilities_dict[vulnerability_name] = vulnerability_json
            self.db_manager.editVulnerability(vulnerability_json.dictionary().copy())
            response.setResponse(True)
            response.setBody(self.vulnerabilities_dict[vulnerability_name].dictionary())
        else:
            response.setReason('Vulnerability doesn\'t exist')
            response.setResponse(False)
            response.setBody(dict())
        return response.dictionary()

    def deleteOne(self, vulnerability_name):
        """
        Deletes a vulnerability from the database.
        :param vulnerability_name: Vulnerability's name string
        :return: Response object containing the status of the request
        """
        response = Response()
        if vulnerability_name in self.vulnerabilities_dict:
            deleted_vulnerability = self.vulnerabilities_dict.pop(vulnerability_name)
            self.db_manager.deleteVulnerability(vulnerability_name)
            response.setResponse(True)
            response.setBody(deleted_vulnerability.dictionary())
        else:
            response.setResponse(False)
            response.setReason('Vulnerability doesn\'t exist')
            response.setBody(dict())
        return response.dictionary()
