#!/usr/bin/python

# Script to check if launchpad is up and usable.
#
# Since this script does some http queries it is a bit slow.  The intent
# is to run it periodically to 'test' launchpad and cache the result
# locally; cronjobs can then check this cached status value to see if
# launchpad is available, and if not, bail out and not bother trying to
# run.

import re
import sys
import feedparser
from datetime import ( datetime, timedelta )
import launchpadlib
from launchpadlib.launchpad import Launchpad

consumer='lpltk'
service_root='production'

def expected_outage():
    """Returns tuple of (start, stop) time for the current or next expected outage"""

    (expected_start, expected_end) = (None, None)

    d = feedparser.parse('http://blog.launchpad.net/category/notifications/feed')
    latest_entry = d['entries'][0]
    notice_html = latest_entry['content'][0]['value']

    date_format_long = ' %H.%M UTC %d of %B %Y'
    date_format_short = ' %H.%M UTC %Y-%m-%d'

    m = re.search("Starts:.*>(.*)<", notice_html)
    if m:
        raw_text = m.group(1)
        text = re.sub(r'(\d+)(?:st|nd|rd|th) ', r'\1 ', raw_text)
        try:
            expected_start = datetime.strptime(text, date_format_long)
        except:
            expected_start = datetime.strptime(text, date_format_short)

    m = re.search('Expected.*back.*by.*>(.*)<', notice_html)
    if m:
        raw_text = m.group(1)
        text = re.sub(r'(\d+)(?:st|nd|rd|th) ', r'\1 ', raw_text)
        try:
            expected_end = datetime.strptime(text, date_format_long)
        except:
            expected_end = datetime.strptime(text, date_format_short)

    return (expected_start, expected_end)


(outage_start, outage_end) = expected_outage()



# Are we in the middle of an expected outage?
if outage_start and outage_end:
    if datetime.now() > outage_start and datetime.now() < outage_end:
        print 'OFFLINE EXPECTED'
        sys.exit(3)

    # Will we be offline shortly?
    pending_offline_time = timedelta(hours=2)
    if datetime.now() + pending_offline_time > outage_start:
        print 'PENDING OFFLINE'
        sys.exit(2)

# Can we at least reach launchpad's api service in minimal read-only mode?
try:
    lp = Launchpad.login_anonymously(consumer, service_root) # Need >= 1.5.1
except:
    print 'OFFLINE UNKNOWN'
    sys.exit(9)

# See if we can access read-write too
try:
    lp = Launchpad.login_with(consumer, service_root)
    print 'UP READWRITE'
except:
    print 'UP READONLY'
    sys.exit(1)

sys.exit(0)
