#!/usr/bin/env python3

import configparser
import datetime as dt
import sys
from os.path import expanduser

import click
import dateparser
from html2text import html2text
from icalendar import Calendar, Event
from O365 import Account, FileSystemTokenBackend

__author__ = "ojas"

CONFIG_FILE_PATH = '~/.o365sync'
CAL_TOKEN_FILE_PATH = '~/.o365cal_token'

AVERAGE_RESOURCE_HOURLY_COST_USD = 100

def eprint(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)

def get_config_file():
    return expanduser(CONFIG_FILE_PATH)

def get_token_backend():
    token_backend = FileSystemTokenBackend(token_filename=expanduser(CAL_TOKEN_FILE_PATH))
    return token_backend

def get_account():
    config = configparser.ConfigParser()
    config.read(get_config_file())
    credentials = (config['credentials']['client_id'], config['credentials']['client_secret'])
    account = Account(credentials, token_backend=get_token_backend())
    return account

@click.group()
def main():
    """
    Simple CLI for querying books on Google Books by Oyetoke Toby
    """
    pass

@main.command()
def login():
    scopes = ['offline_access', 'calendar']
    account = get_account()
    
    account.authenticate(scopes=scopes)#, token_backend=token_backend)

@main.command()
def test():
    account = get_account()
    print ('O365.Account.is_authenticated = %s' % (account.is_authenticated, ))

@main.command()
def setup():
    config = configparser.ConfigParser()
    print("Let's get your Microsoft App credentials")
    client_id = input("Client ID (aka application ID): ")
    client_secret = input('Client secret (aka application password): ')
    config['credentials'] = {}
    config['credentials']['client_id'] = client_id
    config['credentials']['client_secret'] = client_secret
    with open(get_config_file(), 'w') as f:
        config.write(f)

@main.command()
@click.option("--start", default='1 week ago', help='Start date.')
@click.option("--end", default='In 2 weeks', help='End date.')
@click.option("--limit", default=None, type=int, help='Number of events.')
@click.option("--quiet", default=False, type=bool, help='Silent mode.')
#@click.argument('id')
def generate(start='1 week ago', end='In 2 weeks', limit=None, quiet=False):
    account = get_account()

    if not account.is_authenticated:
        eprint('Please login with `o365cal login`')
        sys.exit(1)

    start_date = dateparser.parse(start)
    end_date = dateparser.parse(end)
    if not quiet:
        eprint('Getting events from %s to %s' % (start_date, end_date))

    cal = Calendar()
    cal.add('prodid', '-//Oj D&B Calendar//mxm.dk//')
    cal.add('version', '2.0')

    schedule = account.schedule()

    calendar = schedule.get_default_calendar()

    q = calendar.new_query('start').greater_equal(start_date)
    q.chain('and').on_attribute('end').less(end_date)

    events = calendar.get_events(query=q, include_recurring=True, limit=limit)
    for event_in in events:
        # body = event_in.body

        subject_prefix = ''
        all_attendee_emails = [event_in.organizer.address]
        all_attendee_emails += [a.address for a in event_in.attendees]
        all_attendee_emails = set(all_attendee_emails)
        num_attendees = len(all_attendee_emails)
        if num_attendees:
            num_hours = (event_in.end - event_in.start).total_seconds() / 3600
            if num_hours < 24:
                round_to = 50
                total_cost_rounded = round(num_attendees * AVERAGE_RESOURCE_HOURLY_COST_USD * num_hours/round_to) *  round_to
                subject_prefix = '[$%s]' % (total_cost_rounded)

        event_out = Event()
        event_out.add('summary', ' '.join([subject_prefix, event_in.subject]))
        event_out.add('dtstart', event_in.start)
        event_out.add('dtend', event_in.end)
        event_out.add('location', event_in.location)
        event_out.add('description', html2text(event_in.body))
    #    event_out.add('X-ALT-DESC', event_in.get_body_text())
        event_out['uid'] = event_in.ical_uid
        cal.add_component(event_out)
        
    print(cal.to_ical().decode('utf-8'))

if __name__ == "__main__":
    main()
