#!/usr/bin/env python3

from datetime import datetime, timedelta
from json import dumps, loads
from pathlib import Path
from urllib.request import urlopen
from zoneinfo import ZoneInfo

GRANULARITY = 30
ROOM_SEQUENCE = ('Sondermaschinenbau', 'Smart City Schmiede', 'Sofaecke', 'CTF')
SCHEDULE_URL = 'https://cfp.fairydust.reisen/iger-2022/schedule/export/schedule.json'
TIMEZONE = 'Europe/Berlin'

def parse_duration(s, num_parts):
    duration = 0
    for t in s.split(':', maxsplit=num_parts-1):
        duration *= 60
        duration += int(t)

    return duration

def room_sequence_key(room):
    try:
        return ROOM_SEQUENCE.index(room)
    except ValueError:
        return len(ROOM_SEQUENCE)

def main():
    with urlopen(SCHEDULE_URL) as f:
        data = loads(f.read())

    conference = data['schedule']['conference']

    rooms = {}
    for day in conference['days']:
        for room in conference['rooms']:
            name = room['name']
            if name not in day['rooms']:
                continue
            if name not in rooms:
                rooms[name] = []

            rooms[name] += day['rooms'][name]

    timezone = ZoneInfo(TIMEZONE)

    start_date = None
    end_date = None
    for _, events in rooms.items():
        for event in events:
            date = datetime.fromisoformat(event['date']).astimezone(timezone)
            if start_date is None or date < start_date:
                start_date = date

            event['start_date'] = date

            date += timedelta(seconds=parse_duration(event['duration'], 2)*60)
            if end_date is None or date > end_date:
                end_date = date

            event['end_date'] = date

    timeline = []
    timeslot = parse_duration(conference['timeslot_duration'], 2)
    for offset in range(0, int((end_date-start_date).total_seconds()), GRANULARITY*60):
        date = start_date + timedelta(seconds=offset)
        timeline.append({'date': date.strftime('%Y-%m-%d'), 'start': offset//(timeslot*60)+1, 'time': date.strftime('%H:%M')})

    out_data = {
        'days': [day['date'] for day in conference['days']],
        'end_date': end_date.isoformat(timespec='seconds'),
        'rooms': {name: [{
            'end': int((event['end_date']-start_date).total_seconds())//(timeslot*60)+1,
            'end_time': event['end_date'].strftime('%H:%M'),
            'speaker': ', '.join(person['public_name'] for person in event['persons']),
            'start': int((event['start_date']-start_date).total_seconds())//(timeslot*60)+1,
            'start_time': event['start_date'].strftime('%H:%M'),
            'title': event['title'],
            'url': event['url'],
        } for event in events] for name, events in rooms.items()},
        'room_sequence': sorted(rooms.keys(), key=room_sequence_key),
        'span': GRANULARITY // timeslot,
        'start_date': start_date.isoformat(timespec='seconds'),
        'timeline': timeline,
        'timezone': TIMEZONE,
        'version': data['schedule']['version'],
    }

    with open(Path(__file__).resolve().parent.parent / 'data' / 'schedule.json', 'w') as f:
        f.write(dumps(out_data))

if __name__ == '__main__':
    main()
