#!/usr/bin/env python3

"""
Generates the CSV file that I import into Hootsuite each month to do
the #ApacheBirthday tweets.

Caveats:

The "n years" bit probably doesn't work if you're running it
for a month in the following year. eg, if you run it for January while
it's still December.

This script takes a long time to run because it verifies that projects
actually exist, by loading their website. This is so that we're not
reporting on Attic'ed projects, and subprojects, and so on.
"""

import sys
import json
import re
from datetime import datetime
from urllib.request import urlopen, Request
from urllib.error import URLError, HTTPError

# Set to True to make it noisy
VERBOSE = False

def usage():
    print("Usage: ./birthday.py MONTH - eg, ./birthday.py 07")
    sys.exit(1)

def fetch_url(url, timeout=5):
    """Fetch URL content with timeout and user agent"""
    try:
        req = Request(url, headers={'User-Agent': 'Twitter4Ponies/0.1'})
        with urlopen(req, timeout=timeout) as response:
            return response.read().decode('utf-8'), response.getcode()
    except (URLError, HTTPError) as e:
        return None, None

def main():
    if len(sys.argv) != 2 or not sys.argv[1].isdigit():
        usage()
    
    month = f"{int(sys.argv[1]):02d}"
    if not month:
        usage()
    
    thisyear = datetime.now().year
    
    where = 'https://projects.apache.org/json/foundation/committees.json'
    
    # Fetch the json
    content, status_code = fetch_url(where)
    if not content or status_code != 200:
        print("Error fetching project data")
        sys.exit(1)
    
    try:
        projects = json.loads(content)
    except json.JSONDecodeError as e:
        print(f"Error parsing JSON: {e}")
        sys.exit(1)
    
    day = 1
    hour = 9
    
    for project in projects:
        proj = project.get('id')
        established_date = project.get('established')
        charter = project.get('charter')
        
        if not established_date:
            continue
            
        if not established_date.endswith(f'-{month}'):
            continue
        
        # Skip projects that aren't actually there. (Attic? Subprojects?)
        if VERBOSE:
            print(f"Checking the validity of {proj}", file=sys.stderr)
        
        _, status_code = fetch_url(f"http://{proj}.apache.org/")
        if status_code != 200:
            continue
        
        # Extract year from date
        year_match = re.search(r'(\d{4})', established_date)
        if not year_match:
            continue
            
        year = int(year_match.group(1))
        age = thisyear - year
        
        # Format the CSV output
        date_time = f"{day:02d}/{month}/{thisyear} {hour:02d}:00:00"
        
        years_text = "years" if age > 1 else "year"
        tweet_text = (f"Happy birthday to {project['name']}! {age} {years_text} "
                     f"as an ASF top level project! #ApacheBirthday"
                     f"{charter}"
                     )
        
        url = f"http://{proj}.apache.org/"
        
        print(f'"{date_time}","{tweet_text}","{url}"')
        
        day += 1
        if day > 28:
            day = 1
            hour += 6

if __name__ == "__main__":
    main()
