from __future__ import print_function
import httplib2
import os

from apiclient import discovery
import oauth2client
from oauth2client import client
from oauth2client import tools
import copy
import pytz
import datetime


calendar_id = "me@example.com" #google calendar ID
HOSTNAME = "10.0.0.63" # phone netowrk ip
current_timezone = pytz.timezone('US/Eastern')

try:
    import argparse
    flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
    flags = None

# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/calendar-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/calendar.readonly'
CLIENT_SECRET_FILE = 'client_secret.json' # generated by google
APPLICATION_NAME = 'Google Calendar API Python Quickstart'


def get_credentials():
    """Gets valid user credentials from storage.

    If nothing has been stored, or if the stored credentials are invalid,
    the OAuth2 flow is completed to obtain the new credentials.

    Returns:
        Credentials, the obtained credential.
    """
    home_dir = os.path.expanduser('~')
    credential_dir = os.path.join(home_dir, '.credentials')
    if not os.path.exists(credential_dir):
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir,
                                   'calendar-python-quickstart.json')

    store = oauth2client.file.Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        if flags:
            credentials = tools.run_flow(flow, store, flags)
        else: # Needed only for compatibility with Python 2.6
            credentials = tools.run(flow, store)
        print('Storing credentials to ' + credential_path)
    return credentials

def too_long_break_rec(events_start, events_end):
  # events sorted by begin time
  BREAKS_MAX = 3  # in hours
  if len(events_start) != len(events_end):
    print ("Different number in too_long_break_rec :-7")
  nbr_events = len(events_start)
  if nbr_events >= 2:
    i = 1
    while i < nbr_events and events_end[0] > events_start[i]:
      i = i + 1
    min_break = datetime.timedelta.max
    for j in range(0, i):
      if events_start[i] - events_end[j] < min_break:
        min_break = events_start[i] - events_end[j]
        index_min_break = j
    if min_break > datetime.timedelta(hours = BREAKS_MAX):
      return events_end[index_min_break]
    else:
      ee = events_end[0]

      for i in range(0, nbr_events):
        if events_end[i] <= ee:
          del events_start[i]
      events_end[:] = [e for e in events_end if e > ee]

      return too_long_break_rec(events_start[1:], events_end[1:])
  else:
    return None

def reactivate_at(time):

  response = os.system("ping -c 5 " + HOSTNAME)

  if response == 0:
      present = True
  else:
      present = False

  f = open('heater_command.txt', 'w')

  f.write("Present = " + str(present) + "\nReactivate at = " + str(time))
  f.closed

def main(): # has to be called every 10 minutes

    FMT = '%Y-%m-%dT%H:%M:%S%z'
    FMT_z = '%Y-%m-%dT%H:%M:%S'

    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    service = discovery.build('calendar', 'v3', http=http)
    now_string = datetime.datetime.now(pytz.utc).astimezone(current_timezone).strftime(FMT)
    end_string = (datetime.datetime.now(pytz.utc).astimezone(current_timezone).replace(hour=0, minute=0,second=0,) + datetime.timedelta(1)).strftime(FMT)
    # end_string, next day 00:00:00


    eventsResult = service.events().list(
        calendarId=calendar_id, timeMin=now_string, timeMax=end_string, # fetch all the event of today still to come or occuring now
        singleEvents=True, # let the recurring event appear more than one
        orderBy='startTime').execute() # sort event, avoid queue of recurring event
    events = eventsResult.get('items', [])
    nbr_events = len(events)
    if nbr_events > 0:
      events_end = list()
      events_start = list()
      for event in events:
        start = datetime.datetime.strptime(event.get('start').get('dateTime')[:19],FMT_z) # strptime doesn't work with %z
        end = datetime.datetime.strptime(event.get('end').get('dateTime')[:19],FMT_z)
        events_end.append(end)
        events_start.append(start)

      break_time = too_long_break_rec(copy.deepcopy(events_start), copy.deepcopy(events_end))
      if break_time != None:
        reactivate_at(break_time)

      else: # no break to head home -> last event
        events_end.sort() # sort the endtimes, take care of event if the last event of the day is not the last one to begin
        last_event_end = events_end[nbr_events-1]
        reactivate_at(last_event_end)

    else:
      # no event, -> @ home
      reactivate_at(None)


if __name__ == '__main__':
    main()