from __future__ import absolute_import

from flask import jsonify, request

from . import app
from .errors import ServerError, BadDataError
from .forms import  SignupForm, AddEventForm, CheckinForm
from .models import db_safety, Account, Event, Attendee, Checkin

@app.route('/accounts', methods=['POST'])
def signup():
    try:
      form = SignupForm.from_json(request.json)
    except Exception as e: # Otherwise there's a 400 that's propagated
      raise BadDataError()
    if not form.validate_on_submit():
      raise BadDataError()
    username = form.username.data
    public_key = form.publicKey.data
    if Account.lookup_from_username(username) != None:
      raise ServerError('This account already exists!', status_code=409)
    with db_safety() as session:
        account_id = Account.create(session, username, public_key)
    return jsonify({'message': 'Account successfully created'})

@app.route('/events', methods=['POST'])
def new_event():
    try:
      form = AddEventForm.from_json(request.json)
    except Exception as e: # Otherwise there's a 400 that's propagated
      raise BadDataError()
    if not form.validate_on_submit():
      raise BadDataError()
    name = form.name.data
    start = form.start.data
    end = form.end.data
    description = form.description.data
    if start >= end:
      raise BadDataError()
    with db_safety() as session:
        event_id = Event.create(session, name, start, end, description)
    return jsonify({'message': 'Event successfully created', 'event_id': event_id})

@app.route('/events', methods=['GET'])
# TODO: generalize beyond just user events
def get_events():
    # TODO: add pagination
    attendee_ids = request.args.getlist("attendee_id")
    if len(attendee_ids) != 1:
        raise BadDataError()
    try:
        attendee_id = int(attendee_ids[0])
    except ValueError as e:
        raise BadDataError()
    with db_safety() as session:
        # TODO: check authentication simultaneously to avoid TOCTOU
        # TODO: get rest of event info i.e. attendees
        events = session.query(Event) \
          .join(Attendee, Event.id==Attendee.event_id) \
          .filter(Attendee.account_id == attendee_id).all()
        for event in events:
          attendees = session.query(Attendee) \
            .filter(Attendee.event_id == event.id).all()
          event.attendees = []
          for attendee in attendees:
            event.attendees.append(attendee.account_id)
        # TODO: fix serialization
        events = [{'id': event.id,
          'name': event.name,
          'start' : event.start.strftime("%Y-%m-%dT%H:%M:%S"), # TODO: extract constant
          'end' : event.end.strftime("%Y-%m-%dT%H:%M:%S"),
          'description': event.description,
          'attendees': event.attendees} for event in events
          ]
    return jsonify({"events": events})

@app.route('/checkins', methods=['POST'])
def add_checkin():
    try:
        form = CheckinForm.from_json(request.json)
    except Exception as e: # Otherwise there's a 400 that's propagated
        raise BadDataError()
    if not form.validate_on_submit():
        raise BadDataError()
    event_id = form.eventId.data
    account_id = form.accountId.data
    timestamp = form.timestamp.data
    latitude = form.location.latitude.data
    longitude = form.location.longitude.data
    with db_safety() as session:
        attendee_id = Attendee.lookup_from_ids(account_id, event_id).id
        checkin_id = Checkin.create(session, attendee_id, timestamp, latitude, longitude)
    return jsonify({'message': 'Successfully checked in', 'checkinId': checkin_id})

@@ -3612,12 +3612,1261 @@
 heckin_id%7D)%0A
+%0A@app.route('/checkins', methods=%5B'GET'%5D)%0Adef get_checkins():%0A    event_ids = request.args.getlist(%22event_id%22)%0A    if len(event_ids) != 1:%0A        raise BadDataError()%0A    try:%0A        event_id = int(event_ids%5B0%5D)%0A    except ValueError as e:%0A        raise BadDataError()%0A    with db_safety() as session:%0A        attendees = session.query(Attendee).distinct(Attendee.account_id) %5C%0A          .filter(Attendee.event_id == event_id).all()%0A        attendee_locations = %5B%5D%0A        for attendee in attendees:%0A            attendee_latest_checkin = session.query(Checkin) %5C%0A              .filter(Checkin.attendee_id == attendee.id).order_by(Checkin.timestamp).first()%0A            attendee_username = session.query(Account) %5C%0A              .filter(Account.id == attendee.account_id).first()%0A            try:%0A              attendee_locations.append(%7B%22account_id%22:attendee.account_id, %5C%0A                %22username%22:attendee_username.username, %5C%0A                %22latitude%22:attendee_latest_checkin.latitude, %5C%0A                %22longitude%22:attendee_latest_checkin.longitude%7D)%0A            except Exception as e:%0A                print e, %22attendee probably has not checked in yet%22 #TODO: make this better%0A    return jsonify(%7B%22attendee_locations%22: attendee_locations%7D)%0A

add get attendee locations endpoint to checkins