#!/usr/bin/env python

import sys
from pprint import pformat
import requests
import pyquery
import ssl
import OpenSSL
from urlparse import urlparse, urljoin
from datetime import datetime, timedelta
from pytz import UTC
import logging
logging.getLogger().setLevel(logging.DEBUG)


class AttrDict(dict):
    def __init__(self, *a, **kw):
        dict.__init__(self, *a, **kw)
        self.__dict__ = self

derp = AttrDict()

def die(reason):
    raise SystemExit(reason)

def interact():
    import code
    code.InteractiveConsole(locals=globals()).interact()

class CertificateProblem(Exception):
    pass

class ReachabilityProblem(Exception):
    pass

def decode_ossl_time(t):
    f = '%Y%m%d%H%M%SZ'
    return datetime.strptime(t, f)

class SSLCert(object):
    def __init__(self,x):
        self.x = x
    def notBefore(self):
        return decode_ossl_time(self.x.get_notBefore())
    def notAfter(self):
        return decode_ossl_time(self.x.get_notAfter())
    def commonName(self):
        t = self.x.get_subject().get_components()
        for x in t:
            if x[0] == "CN":
                return x[1]
    def expired(self):
        return datetime.utcnow() > self.notAfter()
    def tooEarly(self):
        return datetime.utcnow() < self.notBefore()
    def validTime(self):
        if not self.expired() and not self.tooEarly():
            return True
        return False
    def expiresSoon(self):
        week = timedelta(days=7)
        then = datetime.utcnow() + week
        return then > self.notAfter()
         

def check_url(url):
    r = requests.get(url,verify=True)
    if r.status_code is not 200:
        raise ReachabilityProblem
    cert = cert_for_url(url)
 
def cert_for_url(url):
    o = urlparse(url)
    if o.scheme != 'https':
        return None

    if not o.port:
        p = 443
    else:
        p = o.port
    c = ssl.get_server_certificate((o.hostname, p))

    return SSLCert(
        OpenSSL.crypto.load_certificate(
            OpenSSL.crypto.FILETYPE_PEM,
            c
        )
    )
    
def main():
    if len(sys.argv) < 2:
        print "usage: %s <url>" % sys.argv[0]
        sys.exit(1)
    do_checks(sys.argv[1])

def do_checks(starturl):
    urlqueue = []
    urlqueue.append(starturl)
    while len(urlqueue):
        urlqueue.extend(check_url(urlqueue.pop()))

if __name__ == '__main__':
    main()
