# api key from gurgle AIzaSyDDFrIPAMv3HS6PXTDcWfiUys8si_-yZ-c
import numpy as np
from gmplot import GoogleMapPlotter
from random import random
import json
from pprint import PrettyPrinter
import matplotlib.pyplot as plt
import matplotlib
from matplotlib.ticker import FormatStrFormatter
import shutil
import requests
from geopy import distance

def getMapImage(bbox=[38.865,-77.072,38.876,-77.001], apiKey="GKvj5HV6DLjqJT8awam4KQL3d26GP1M1", mapType="sat", mapSize=[600,400]):
    req = "https://www.mapquestapi.com/staticmap/v5/map?key={}&boundingBox={}&type={}&size={}".format(apiKey,','.join(map(str,bbox)),mapType,','.join(map(str,mapSize)))
    response = requests.get(req, stream=True)
    with open('mapImg.jpeg', 'wb') as out_file:
        shutil.copyfileobj(response.raw, out_file)
    del response

def inflateBounds(bbox=[38.865,-77.072,38.876,-77.001], amt=0.001):
    return [bbox[0]-amt, bbox[1]-amt, bbox[2]+amt, bbox[3]+amt]

def calculateDistance(pt1, pt2):
    # 2D geodesic distance in meters
    distance_2d = distance.distance(pt1[:2], pt2[:2]).m
    # 3D euclidean distance
    distance_3d = np.sqrt(distance_2d**2 + (pt2[2] - pt1[2])**2)
    return distance_3d

def rejectOutliers(data, m = 2.):
    d = np.abs(data - np.median(data))
    mdev = np.median(d)
    s = d/mdev if mdev else 0.
    # return data[s<m]
    return s<m

filenames = ["/home/llh/ros-kubernetes/plottingTools/pingStats_june_3rd_2022/pingStats.json",
             "/home/llh/ros-kubernetes/plottingTools/pingStats_june_3rd_2022/pingStatsDocker.json",
             "/home/llh/ros-kubernetes/plottingTools/pingStats_june_3rd_2022/pingStatsKubernetes.json"]
# filenames = ["/home/llh/ros-kubernetes/plottingTools/pingStats_may_29th_2022/pingStats.json",
#              "/home/llh/ros-kubernetes/plottingTools/pingStats_may_29th_2022/pingStatsDocker.json"]
             # "/home/llh/ros-kubernetes/plottingTools/pingStats_may_29th_2022/pingStatsKubernetes.json"]
plotColors = ["orange","slateblue","mediumspringgreen"]
# reference point of the base station
anchorPoint = [37.196927, -80.578399, 452.7027587890625]

# potentially the least python-ish way to handle this
for (i, fn) in enumerate(filenames):
    with open(fn) as file:
        data = json.load(file)

    # need to iterate over endpoints as well
    endpoint = "192.168.111.200"
    # ignore time stamps for now
    timelessData = []
    for minuteData in data[endpoint].values():
        for pt in minuteData:
            if ("lat" in pt):
                timelessData.append(pt)

    dists = np.array([calculateDistance([dataPoint["lat"], dataPoint["long"], dataPoint["alt"]],anchorPoint) for dataPoint in timelessData])
    avgLatencies = np.array([dataPoint["avg"] for dataPoint in timelessData])
    maskArray = rejectOutliers(avgLatencies, m=2.0)
    filteredLatencies = avgLatencies[maskArray]
    filteredDistances = dists[maskArray]
    print("removed {outliers} outliers from the dataset".format(outliers=np.size(maskArray) - np.count_nonzero(maskArray)))

    # calculate best fit line
    func = np.poly1d(np.polyfit(filteredDistances, filteredLatencies, 1))
    evenDists = np.linspace(np.min(filteredDistances),np.max(filteredDistances),10)
    plt.scatter(filteredDistances, filteredLatencies, s=12, c=plotColors[i], label=[f.split('/') for f in filenames][i][-1])
    plt.plot(evenDists, func(evenDists), c=plotColors[i], linewidth=1.5)

plt.ticklabel_format(style='plain') # to prevent scientific notation
plt.ticklabel_format(useOffset=False)

plt.title('Network Latency vs Distance')
plt.xlabel("Distance")
plt.ylabel("Latency")
plt.legend()
# plt.show()
plt.savefig("scatterPlot.jpeg", dpi=400)
