#!/usr/bin/python
# -*- coding: utf-8 -*-
from armory.database.repositories import VulnRepository
from armory.included.ReportTemplate import ReportTemplate
import json
import subprocess


class Report(ReportTemplate):
    """
    This report pulls out any Nessus/nmap vulnerability findings,
    looks for public exploits, and points to the exploits."""

    name = "Exploitable"

    def __init__(self, db):
        self.db = db

        self.Vulnerability = VulnRepository(db, self.name)

    def set_options(self):
        super(Report, self).set_options()

    def run(self, args):
        vulns = self.Vulnerability.all()
        res = self.writePlain(vulns, args)

        self.process_output(res, args)

    def getEDB(self, thing):
        searchsploit = json.loads(
            subprocess.check_output("searchsploit -j {}".format(thing), shell=True)
        )
        return searchsploit

    def vulnInfo(self, findings):
        res = []
        if len(findings) > 0:
            for finding in findings:
                if finding.exploit_reference is not None:

                    res.append(finding.name)
                    vulnServices = finding.ports
                    res.append("Affected Hosts and Services:")
                    for service in vulnServices:

                        res.append(
                            "\t{} : {}/{}".format(
                                service.ip_address.ip_address,
                                service.proto,
                                service.port_number,
                            )
                        )

                    res.append("")

                    for key in finding.exploit_reference.keys():
                        if key == "metasploit":

                            res.append("Metasploit:")
                            for thing in finding.exploit_reference[key]:

                                res.append(
                                    "\t"
                                    + 'msf> search name:"{}" type:exploit'.format(  # noqa: W503
                                        thing
                                    )
                                )
                            res += ["", ""]

                        if key == "edb-id":

                            res.append("exploit-database:")
                            for thing in finding.exploit_reference[key]:
                                edb = self.getEDB(thing)
                                if edb["RESULTS_SHELLCODE"]:
                                    for sc in edb["RESULTS_SHELLCODE"]:
                                        res.append(sc)
                                        res.append("")

                                if edb["RESULTS_EXPLOIT"]:
                                    i = 0
                                    while i < len(edb["RESULTS_EXPLOIT"]):

                                        res.append("\tExploit-DB Title:")
                                        res.append(
                                            "\t\t" + edb["RESULTS_EXPLOIT"][i]["Title"]
                                        )
                                        res.append("\tLocal Path to Exploit:")
                                        res.append(
                                            "\t\t" + edb["RESULTS_EXPLOIT"][i]["Path"]
                                        )
                                        url = "https://exploit-db.com/exploits/"
                                        url += edb["RESULTS_EXPLOIT"][i]["EDB-ID"]

                                        res.append("\tPossible url for exploit:")
                                        res.append("\t\t" + url)
                                        i += 1
                                        res.append("")

                    res.append("#" * 20)
        return res

    def writePlain(self, vulns, args):
        res = []

        # if os.path.isfile(fileName):
        # 	print (fileName,"exists.")
        # 	answered = False

        # 	while answered == False:
        # 		rerun = raw_input("Would you like to [o]verwrite the file, or change the file [n]ame? ")
        # 		if rerun.lower() == 'o':
        # 			with open(fileName,"w") as file:
        # 				answered = True

        # 		elif rerun.lower() == 'n':
        # 			new = False
        # 			while new == False:
        # 				newFile = raw_input("enter a new file name: ")
        # 				if not os.path.isfile(newFile):
        # 					fileName = newFile
        # 					answered = True
        # 					new = True
        # 				else:
        # 					print "That file exists as well"
        # 		else:
        # 			"Please enter \'o\' to overwrite the file, \'n\' to change the file name"

        high = []
        medium = []
        low = []
        info = []

        for vuln in vulns:
            if vuln.exploit_reference is not None:
                if vuln.severity >= 4:
                    # if vuln not in high:
                    high.append(vuln)
                if vuln.severity == 3:
                    # if vuln not in medium:
                    medium.append(vuln)
                if vuln.severity == 2:
                    # if vuln not in low:
                    low.append(vuln)
                if vuln.severity <= 1:
                    # if vuln not in info:
                    info.append(vuln)

        if high:

            res.append("High Severity Findings:")
            res += self.vulnInfo(high)

        if medium:

            res.append("Medium Severity Findings:")
            res += self.vulnInfo(medium)

        if low:

            res.append("Low Severity Findings:")
            res += self.vulnInfo(low)

        if info:
            res.append("Info Severity Findings:")
            res += self.vulnInfo(info)

        return res
