import calendar, logging
from time import gmtime
from hashlib import sha1

class Vulnerability(object):
    '''К этому типу должны приводиться все уязвимости перед сохранением
    body хранит специфичные для сканера поля.
    '''
    def __init__(self, target, port, scanner, text, VulnerabilityTypes, Score, protocol,
                 UpdateDate=None, scan_date=None, Complexity=None, Access=None, CWEID=None, Authentication=None,
                 Integ=None, PublishDate=None, Conf=None, ofExploits=0, Avail=None,
                 CVEID=None, references=None, GainedAccessLevel=None, false_positive=False,
                 fixed=None, body=None):
        scan_date = scan_date if scan_date is not None else calendar.timegm(gmtime())
        references = references or []
        body = body or {}

        self.name = self.construct_cve_name(VulnerabilityTypes, protocol, target, port, credentials, uri, params)

        self.data = {
            "target" : target,
            "port" : int(port),
            "Scanner": scanner,
            "Scan_date": scan_date,
            "Name":  name,
            "UpdateDate": UpdateDate,
            "VulnerabilityTypes": VulnerabilityTypes,
            "Complexity": Complexity,
            "text": text,
            "Access": Access,
            "CWEID": CWEID,
            "Hash": sha1(self.name.encode('utf-8')).hexdigest(),
            "Authentication": Authentication,
            "Integ": Integ,
            "PublishDate": PublishDate,
            "Conf": Conf,
            "ofExploits": ofExploits,
            "Score": Score,
            "Avail": Avail,
            "CVEID": CVEID,
            "References": references,
            "GainedAccessLevel": GainedAccessLevel,
            "FalsePositive": false_positive,
            "Fixed": fixed,
            "Body": body
        }

    @staticmethod
    def construct_cve_name(VulnerabilityTypes, protocol, target, port, credentials, uri, params):
        # vuln_type:host:port:protocol:credentials:uri:params
        return "{}:{}:{}:{}:{}:{}:{}".format(
            VulnerabilityTypes,
            target,
            port,
            protocol,
            credentials,
            uri,
            params)

    def __str__(self):
        return self.data

    def __repr__(self):
        return self.name
