import time
import json
from aux_functions import signal_functions as signal
from drone_config import drone_config as drone_config
from aux_functions import iot_functions as iot
import numpy as np
from aux_functions import helper_functions as helper

#Read drone configuration data
anmail_token = drone_config.get_param("anmail_token")
antower_token = drone_config.get_param("antower_token")
numTrials = drone_config.get_param("numTrials")


#Download waypoints
def download_waypoints(tower_token):
    requestHeader = {'Authorization': ('Bearer ' + tower_token)}
    requestBody = ''
    requestURL = 'https://tower.anomaaaerospace.com/APIs/downloadwaypoints.php'

    requestResponse = iot.anomaa_client(requestHeader, requestURL, requestBody)

    return requestResponse



#Log on to service and retrieve flight plan
def anmail_logon():
    #Establish comms with Anomaa Mail server
    requestHeader = {'Authorization': ('Bearer ' + anmail_token)}
    request_id = 'req' + str(time.time())
    comm_purpose = 'logon'

    requestBody = {'requestid': request_id, 'commpurpose': comm_purpose}
    requestBodyJSON = json.dumps(requestBody)
    requestURL = 'https://anmail.anomaaaerospace.com/modules/dronecomm.php'

    responseStatus = 0
    while (responseStatus != 200):
        requestResponse = iot.anomaa_client(requestHeader, requestURL, requestBodyJSON)
        responseStatus = requestResponse.status_code

        if (responseStatus == 401):
            signal.raiseFlag("Unauthorized")
        elif (responseStatus == 408):
            signal.raiseFlag("RunawayAC")

        time.sleep(drone_config.get_param("logonTrialInterval"))
    

    #Retrieve route
    responseText = json.loads(requestResponse.text)
    routePlan = responseText['routeplan']
    routeID = responseText['routeid']
    takeoffIncluded = responseText['takeoffIncluded']
    landIncluded = responseText['landIncluded']
    landLocation = responseText['landLocation']
    landBaseID = responseText['landBaseID']

    #File flight plan
    requestHeaderA = {'Authorization': ('Bearer ' + antower_token), 'use_case': "mail"}
    requestBodyA = routePlan
    requestURLA = 'https://tower.anomaaaerospace.com/APIs/fileflightplan.php'

    counterValue = numTrials
    while (counterValue > 0):
        requestResponseA = iot.anomaa_client(requestHeaderA, requestURLA, requestBodyA)
        responseStatusA = requestResponseA.status_code

        if (responseStatusA == 200):
            break

        counterValue = counterValue - 1

        time.sleep(drone_config.get_param("flightPlanTrialInterval"))

        
    if (counterValue == 0):
        #Failed to file flight plan
        signal.raiseFlag("FlightPlanFailed")
        
        return -1


    #Download waypoints
    counterValue = numTrials
    while (counterValue > 0):
        requestResponseC = download_waypoints(antower_token)

        if (requestResponseC.status_code == 200) or (requestResponseC.status_code == 201):
            break

        counterValue = counterValue - 1

        time.sleep(drone_config.get_param("waypointsTrialInterval"))
    
    if (counterValue == 0):
        #Failed to retrieve waypoints
        signal.raiseFlag("WaypointsDownloadFailed")
        return -1
    else:
        responseTextC = json.loads(requestResponseC.text)
        logon_response = {'route_id': routeID, 'flight_plan': responseTextC['flight_plan'], \
                            'evasion_maneuvers': responseTextC['evasion_maneuvers'], 'waypoints': responseTextC['waypoints'], \
                            'num_waypoints': responseTextC['num_waypoints'], 'takeoff_included' : takeoffIncluded, 'velocities' : responseTextC['velocities'], \
                                'land_included' : landIncluded, 'land_location' : landLocation, 'land_base' : landBaseID}

        #Provide feedback to Anomaa Mail server
        requestStatus = 'closed'
        comm_purpose = 'feedback'
        requestBodyB_i = {'requestid': request_id, 'commpurpose': comm_purpose, 'requeststatus': requestStatus}
        requestBodyB = json.dumps(requestBodyB_i)

        counterValue = numTrials
        while (counterValue > 0):
            requestResponseB = iot.anomaa_client(requestHeader, requestURL, requestBodyB)

            if (requestResponseB.status_code == 200):
                break

            counterValue = counterValue - 1

            time.sleep(drone_config.get_param("feedbackTrialInterval"))
        
        if (counterValue == 0):
            #Failed to send feedback
            signal.raiseFlag("FeedbackFailed")
            
            return -1
        
        
        signal.raiseFlag("LogonSuccessful")

        return logon_response



#Logoff from service
def anmail_logoff():
    #terminate comms with ATC server
    requestHeaderA = {'Authorization': ('Bearer ' + antower_token)}
    requestBodyA = ''
    requestURL_A = 'https://tower.anomaaaerospace.com/APIs/endflight.php'
    tower_logoff_response = iot.anomaa_client(requestHeaderA, requestURL_A, requestBodyA)

    #terminate comms with anmail server
    requestHeaderB = {'Authorization': ('Bearer ' + anmail_token)}
    request_id = 'req' + str(time.time())
    comm_purpose = 'logoff'
    requestBodyB_i = {'requestid': request_id, 'commpurpose': comm_purpose}
    requestBodyB = json.dumps(requestBodyB_i)
    requestURL_B = 'https://anmail.anomaaaerospace.com/modules/dronecomm.php'
    anmail_logoff_response = iot.anomaa_client(requestHeaderB, requestURL_B, requestBodyB)

    signal.raiseFlag("LogoffSuccessful")



#Check in with anmail server
def anmail_checkin(routeID):
    requestHeaderA = {'Authorization': ('Bearer ' + anmail_token)}
    request_id = 'req' + str(time.time())
    comm_purpose = 'checkin'
    requestBodyA_i = {'requestid': request_id, 'commpurpose': comm_purpose, 'routeid': routeID}
    requestBodyA = json.dumps(requestBodyA_i)
    requestURL = 'https://anmail.anomaaaerospace.com/modules/dronecomm.php'

    requestResponseA = iot.anomaa_client(requestHeaderA, requestURL, requestBodyA)
    responseTextA = json.loads(requestResponseA.text)

    if (responseTextA == 'Checkin acknowledged.'):
        signal.raiseFlag("CheckinAcknowledged")

        result = 0
    else:
        routeID = responseTextA['routeid']
        routePlan = responseTextA['routeplan']
        takeoffIncluded = responseTextA['takeoffIncluded']
        landIncluded = responseTextA['landIncluded']
        landLocation = responseTextA['landLocation']
        landBaseID = responseTextA['landBaseID']

        #Request reroute
        numRerouteTrials = numTrials
        
        routeList = routeID.split("_")
        if (routeList[0] == "system"):
            pass
        elif (routeList[0] == "land"):
            signal.raiseFlag("CompulsoryLand")

            return -2
        else:

            while (numRerouteTrials > 0):
                requestHeaderB = {'Authorization': ('Bearer ' + antower_token)}
                requestBodyB = routePlan
                requestURL_B = 'https://tower.anomaaaerospace.com/APIs/rerouteflight.php'

                requestResponseB = iot.anomaa_client(requestHeaderB, requestURL_B, requestBodyB)
                responseStatusB = requestResponseB.status_code

                if (responseStatusB == 200):
                    break

                numRerouteTrials = numRerouteTrials - 1

                time.sleep(drone_config.get_param("routeRequestInterval")) 

            
        if (numRerouteTrials == 0):
            signal.raiseFlag("RerouteRequestDenied")

            result = -1
        else:
            #Feedback
            requestStatus = 'closed'
            comm_purpose = 'feedback'
            requestBodyC_i = {'requestid': request_id, 'commpurpose': comm_purpose, 'requeststatus': requestStatus}
            requestBodyC = json.dumps(requestBodyC_i)

            requestResponseC = iot.anomaa_client(requestHeaderA, requestURL, requestBodyC)

            #Request waypoints
            requestBodyD = ''
            requestURL_D = 'https://tower.anomaaaerospace.com/APIs/downloadwaypoints.php'

            requestResponseD = iot.anomaa_client(requestHeaderB, requestURL_D, requestBodyD)
            responseStatusD = requestResponseD.status_code
            responseTextD = json.loads(requestResponseD.text)

            if (responseStatusD == 200):
                result = {'flight_plan': responseTextD['flight_plan'], 'evasion_maneuvers': responseTextD['evasion_maneuvers'], 'waypoints': responseTextD['waypoints'], 'num_waypoints': responseTextD['num_waypoints'], \
                          'route_id': routeID, 'takeoff_included' : takeoffIncluded, 'land_included' : landIncluded, 'land_location' : landLocation, 'land_base' : landBaseID}
            else:
                result = 0

            signal.raiseFlag("CheckinAcknowledged")

    return result


#report position to Anomaa Tower server
def antower_update(data_to_tower):
    requestURL = 'https://tower.anomaaaerospace.com/APIs/sendreceiveupdate.php'
    requestHeader = {'Authorization': ('Bearer ' + antower_token)}

    odid_data = helper.param_from_file("odid_data") #retrieve ODID data

    if (odid_data["location_state"][6] < (time.time() - 60)): #check if ODID data received over BLE is current
        requestBody_i = {'own' : data_to_tower}
    else:
        requestBody_i = {'own' : data_to_tower, odid_data["uas_id"] : odid_data["location_state"]}

    requestBody = json.dumps(requestBody_i)

    requestResponse = iot.anomaa_client(requestHeader, requestURL, requestBody)

    if (requestResponse.status_code == 200):
        signal.raiseFlag("UpdateSuccessful")

        return (json.loads(requestResponse.text))
    else:
        signal.raiseFlag("UpdateNotSuccessful")

        return ({"traffic_data" : []})


#get live base location
def get_live_posn(land_base):
    requestHeader = {'Authorization': ('Bearer ' + anmail_token)}
    requestBody = land_base
    requestURL = 'https://tower.anomaaaerospace.com/APIs/landpositiondownload.php'

    requestResponse = iot.anomaa_client(requestHeader, requestURL, requestBody)

    live_posn = np.zeros(3)

    if (requestResponse.status_code == 200):
        lat, lon, alt = requestResponse.text.split(',')

        live_posn[0] = float(lat)
        live_posn[1] = float(lon)
        live_posn[2] = float(alt)    

    return live_posn


#log fuel
def log_fuel(fuel_val):
    requestHeader = {'Authorization': ('Bearer ' + anmail_token)}
    requestBody = json.dumps(fuel_val)
    requestURL = 'https://anmail.anomaaaerospace.com/modules/logfuel.php'

    requestResponse = iot.anomaa_client(requestHeader, requestURL, requestBody)



#Log signal status
def log_signal(signalStatus):
    requestHeader = {'Authorization': ('Bearer ' + anmail_token)}
    requestBody = json.dumps(signalStatus)
    requestURL = 'https://anmail.anomaaaerospace.com/modules/logsignalstatus.php'

    requestResponse = iot.anomaa_client(requestHeader, requestURL, requestBody)



#Request takeoff
def requestTakeoff():
    requestHeaderA = {'Authorization': ('Bearer ' + anmail_token)}
    request_id = 'req' + str(time.time())
    comm_purpose = 'requestTakeoff'
    requestBodyA_i = {'requestid': request_id, 'commpurpose': comm_purpose}
    requestBodyA = json.dumps(requestBodyA_i)
    requestURL = 'https://anmail.anomaaaerospace.com/modules/dronecomm.php'

    requestResponseA = iot.anomaa_client(requestHeaderA, requestURL, requestBodyA)
    responseTextA = json.loads(requestResponseA.text)

    if (responseTextA == 'Cleared for takeoff'):
        returnStruct = {'value' : True, 'requestID' : request_id}
        
        return returnStruct

    else:
        returnStruct = {'value' : False, 'requestID' : request_id}
        
        return returnStruct

def requestLand():
    requestHeaderA = {'Authorization': ('Bearer ' + anmail_token)}
    request_id = 'req' + str(time.time())
    comm_purpose = 'requestLand'
    requestBodyA_i = {'requestid': request_id, 'commpurpose': comm_purpose}
    requestBodyA = json.dumps(requestBodyA_i)
    requestURL = 'https://anmail.anomaaaerospace.com/modules/dronecomm.php'

    requestResponseA = iot.anomaa_client(requestHeaderA, requestURL, requestBodyA)
    responseTextA = json.loads(requestResponseA.text)

    return responseTextA


#test connection
def testInternetConnection():
    land_base = "kumasi1"

    requestHeader = {'Authorization': ('Bearer ' + anmail_token)}
    requestBody = land_base
    requestURL = 'https://tower.anomaaaerospace.com/APIs/landpositiondownload.php'

    try:
        requestResponse = iot.anomaa_client(requestHeader, requestURL, requestBody)
    except:
        return False

    return True