from ..Utilities.util import *
from ...Dependencies.Filters.supportMethods import *

HostInfo = namedtuple(field_names='cert hostname peername', typename='HostInfo')

def getCertificateDuration(hostClientName,timeout,maxWorker):
    if ".parablu.com" in hostClientName:
        pass
    else:
        # hostClientName = findHostNameWithSystem(hostClientName)
        print(hostClientName)
        print("...........................Line 12")
        

    try:
        print(hostClientName)
        print("...........................Line 17")
        HOSTS = [(hostClientName, 443),]
        
        timeout = timeout
        with concurrent.futures.ThreadPoolExecutor(max_workers=maxWorker) as e:
            for hostinfo in e.map(lambda x: get_certificate(x[0], x[1]), HOSTS,timeout = timeout):
                print_basic_info(hostinfo)

        print("Check this line")
        print(hostinfo.cert.not_valid_after)
        sslExpiry = hostinfo.cert.not_valid_after
        curr_time = round(time.time()*1000)
        print("Milliseconds since epoch:",curr_time)

        sslExp = datetime.strptime(str(sslExpiry), "%Y-%m-%d %H:%M:%S")

        sslExper = sslExp.strftime("%d %b %Y")
        sslMilli = int(sslExpiry.timestamp() * 1000)

        totalDays = sslMilli - curr_time
        print(totalDays)

        seconds, totalDays = divmod(totalDays,1000)
        minutes, seconds = divmod(seconds, 60)
        hours, minutes = divmod(minutes, 60)
        days, hours = divmod(hours, 24)
        seconds = seconds + totalDays/1000

        duration = days
        print(days)
    except:
        duration = "N/A"


    return duration


def verify_cert(cert, hostname):
    cert.has_expired()


def get_certificate(hostname, port):
    hostname_idna = idna.encode(hostname)
    sock = socket()

    sock.connect((hostname, port))
    peername = sock.getpeername()
    ctx = SSL.Context(SSL.SSLv23_METHOD) # most compatible
    ctx.check_hostname = False
    ctx.verify_mode = SSL.VERIFY_NONE

    sock_ssl = SSL.Connection(ctx, sock)
    sock_ssl.set_connect_state()
    sock_ssl.set_tlsext_host_name(hostname_idna)
    sock_ssl.do_handshake()
    cert = sock_ssl.get_peer_certificate()
    crypto_cert = cert.to_cryptography()
    sock_ssl.close()
    sock.close()

    return HostInfo(cert=crypto_cert, peername=peername, hostname=hostname)


def get_alt_names(cert):
    try:
        ext = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName)
        return ext.value.get_values_for_type(x509.DNSName)
    except x509.ExtensionNotFound:
        return None

def get_common_name(cert):
    try:
        names = cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME)
        return names[0].value
    except x509.ExtensionNotFound:
        return None



def get_issuer(cert):
    try:
        names = cert.issuer.get_attributes_for_oid(NameOID.COMMON_NAME)
        return names[0].value
    except x509.ExtensionNotFound:
        return None

def print_basic_info(hostinfo):
    print(hostinfo.cert.not_valid_after)

def check_it_out(hostname, port):
    hostinfo = get_certificate(hostname, port)
    print_basic_info(hostinfo)

