# -*- coding: utf-8 -*-
#

from socket import gaierror, gethostbyname_ex

from asn1crypto import ocsp
from OpenSSL.crypto import FILETYPE_ASN1, dump_certificate

from ..compat import urlsplit
from ..ssl_wrap_socket import _openssl_connect


def probe_connection(url):
    parsed_url = urlsplit(url)

    # DNS lookup
    try:
        actual_hostname, aliases, ips = gethostbyname_ex(parsed_url.hostname)
        ret = {
            'url': url,
            'input_hostname': parsed_url.hostname,
            'actual_hostname': actual_hostname,
            'aliases': aliases,
            'ips': ips,
        }
    except gaierror as e:
        return {'err:': e}
    connection = _openssl_connect(parsed_url.hostname, parsed_url.port)

    # certificates
    certificates = []
    for cert_openssl in connection.get_peer_cert_chain():
        cert_der = dump_certificate(FILETYPE_ASN1, cert_openssl)
        cert = ocsp.Certificate.load(cert_der)
        ocsp_uris = cert.ocsp_urls

        if len(ocsp_uris) == 1:
            parsed_ocsp_url = urlsplit(ocsp_uris[0])

            # DNS lookup for OCSP server
            try:
                actual_hostname, aliases, ips = gethostbyname_ex(
                    parsed_ocsp_url.hostname)
                ocsp_status = {
                    'input_url': ocsp_uris[0],
                    'actual_hostname': actual_hostname,
                    'aliases': aliases,
                    'ips': ips,
                }
            except gaierror as e:
                ocsp_status = {
                    'input_url': ocsp_uris[0],
                    'error': e,
                }
        else:
            ocsp_status = {}

        certificates.append(
            {'hash': cert.subject.sha1,
             'name': cert.subject.native,
             'issuer': cert.issuer.native,
             'serial_number': cert.serial_number,
             'ocsp': ocsp_status,
             })

    ret['certificates'] = certificates
    return ret
