from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from __future__ import unicode_literals, absolute_import
# All the functionality needed to connect to Runkeeper
from rowers.imports import *

# Python
import gzip

import base64
from io import BytesIO


from rowsandall_app.settings import (
    C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET,
    STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET,
    TP_CLIENT_ID, TP_CLIENT_SECRET,
    TP_REDIRECT_URI,TP_CLIENT_KEY,
    )

tpapilocation = "https://api.trainingpeaks.com"

from celery import Celery,app
from django_rq import job
import time
#from async_messages import message_user,messages

oauth_data = {
    'client_id': TP_CLIENT_ID,
    'client_secret': TP_CLIENT_SECRET,
    'redirect_uri': TP_REDIRECT_URI,
    'autorization_uri': "https://oauth.trainingpeaks.com/oauth/authorize?",
    'content_type': 'application/x-www-form-urlencoded',
#    'content_type': 'application/json',
    'tokenname': 'tptoken',
    'refreshtokenname': 'tprefreshtoken',
    'expirydatename': 'tptokenexpirydate',
    'bearer_auth': False,
    'base_url': "https://oauth.trainingpeaks.com/oauth/token",
    'scope':'write',
    }

from rowers.rower_rules import is_workout_user


# Checks if user has UnderArmour token, renews them if they are expired
def tp_open(user):
    return imports_open(user, oauth_data)

# Refresh ST token using refresh token
def do_refresh_token(refreshtoken):
    return imports_do_refresh_token(refreshtoken, oauth_data)

# Exchange access code for long-lived access token
def get_token(code):
    client_auth = requests.auth.HTTPBasicAuth(TP_CLIENT_KEY, TP_CLIENT_SECRET)
    post_data = {
	"client_id":TP_CLIENT_KEY,
        "grant_type": "authorization_code",
        "code": code,
        "redirect_uri":TP_REDIRECT_URI,
	"client_secret": TP_CLIENT_SECRET,
    }
    headers = {
	'Content-Type': 'application/x-www-form-urlencoded',
    }

    try:
        response = requests.post(
        "https://oauth.trainingpeaks.com/oauth/token",
        data=post_data
        )
    except:
        return 0,0,0


    try:
        token_json = response.json()
        thetoken = token_json['access_token']
        expires_in = token_json['expires_in']
        refresh_token = token_json['refresh_token']
    except KeyError:
        thetoken = 0
        expires_in = 0
        refresh_token = 0

    return thetoken,expires_in,refresh_token

# Make authorization URL including random string
def make_authorization_url(request):
    return imports_make_authorization_url(oauth_data)


def getidfromresponse(response):
    t = json.loads(response.text)

    links = t["_links"]

    id = links["self"][0]["id"]

    return int(id)

def createtpworkoutdata(w):
    filename = w.csvfilename
    row = rowingdata(csvfile=filename)
    tcxfilename = filename[:-4]+'.tcx'
    try:
        newnotes = w.notes+'\n from '+w.workoutsource+' via rowsandall.com'
    except TypeError:
        newnotes = 'from '+w.workoutsource+' via rowsandall.com'

    row.exporttotcx(tcxfilename,notes=newnotes)

    return tcxfilename


def tp_check(access_token):
    headers = {
        "Content-Type": "application/json",
	'Accept': 'application/json',
        'authorization': 'Bearer %s' % access_token
    }

    resp = requests.post(tpapilocation+"/v1/info/version",
                         headers=headers)

    return resp

def uploadactivity(access_token,filename,description='',
                   name='Rowsandall.com workout'):

    data_gz = BytesIO()
    with open(filename,'rb') as inF:
        s = inF.read()
        with gzip.GzipFile(fileobj=data_gz,mode="w") as gzf:
            gzf.write(s)


    headers = {
        'Content-Type': 'application/json',
	'Accept': 'application/json',
        'Authorization': 'Bearer %s' % access_token
    }



    data = {
        "UploadClient": "rowsandall",
        "Filename": filename,
        "SetWorkoutPublic": True,
        "Title":name,
        "Type": "rowing",
        "Comment": description,
        "Data": base64.b64encode(data_gz.getvalue()).decode("ascii")
        }

    resp = requests.post(tpapilocation+"/v1/file",
                        data = json.dumps(data),
                        headers=headers)

    if resp.status_code != 200:
        return 0,resp.reason,resp.status_code,headers
    else:
        return resp.json()[0]["Id"],"ok",200,""

    return 0,0,0,0


def workout_tp_upload(user,w):
    message = "Uploading to TrainingPeaks"
    tpid = 0
    r = w.user

    thetoken = tp_open(r.user)

    # need some code if token doesn't refresh


    if (is_workout_user(user,w)):
        tcxfile = createtpworkoutdata(w)
        if tcxfile:
            res,reason,status_code,headers = uploadactivity(
                thetoken,tcxfile,
                name=w.name
            )
            if res == 0:
                message = "Upload to TrainingPeaks failed with status code "+str(status_code)+": "+reason
                w.tpid = -1
                try:
                    os.remove(tcxfile)
                except WindowsError:
                    pass

                return message,tpid

            else: # res != 0
                w.uploadedtotp = res
                tpid = res
                w.save()
                os.remove(tcxfile)
                return 'Successfully synchronized to TrainingPeaks',tpid

        else: # no tcxfile
            message = "Upload to TrainingPeaks failed"
            w.uploadedtotp = -1
            tpid = -1
            w.save()
            return message,tpid
    else: # not allowed to upload
        message = "You are not allowed to export this workout to TP"
        tpid = 0
        return message,tpid

    return message,tpid
