#!/usr/bin/python3
from ip2geotools_locator import Locator
from tqdm import tqdm
from collections import namedtuple
import json, csv

Location = namedtuple('Location', 'latitude longitude')
locator = Locator(False)
uncalculated_probes = []

with open("probes.json", 'r') as f:
    probes = json.load(f)

with open("data.csv", "w") as csv_file:
    csv_writer = csv.writer(csv_file)
    csv_writer.writerow(['IP Address', 'Original: lat', 'Original: lon', 'DbIpCity: lat', 'DbIpCity: lon', 'HostIP: lat', 'HostIP: lon', 'Ip2location: lat', 'Ip2location: lon',
                         'Ipstack: lat', 'Ipstack: lon', 'MaxMind_GeoLite2City: lat', 'MaxMind_GeoLite2City: lon', 'Eurek: lat', 'Eurek: lon','GeobytesCityDetails: lat', 'GeobytesCityDetails: lon',
                         'IP_Info: lat', 'IP_Info: lon', 'DbIpWeb: lat', 'DbIpWeb: lon', 'IP2Location_Web: lat', 'IP2Location_Web: lon',  'MaxMindGeoIp2City: lat', 'MaxMindGeoIp2City: lon',
                         'NeustarWeb: lat', 'NeustarWeb: lon',  'Skyhook: lat', 'Skyhook: lon',
                         'Average: lat', 'Average: lon', 'Median: lat', 'Median: lon', 'Clustering: lat', 'Clustering: lon'])

    none_location = Location(None, None)
    
    for probe in tqdm(probes):
        ip = probe["address_v4"]
        original_latitude = probe["latitude"]
        original_longitude = probe["longitude"]
        tqdm.write("Gathering location info for IP address: " + ip)
        
        locator.fetch_locations(ip)
        calculated = locator.calculate(median=True, clustering=True)

        get_locations = locator.locations

        if "DbIpCity" not in get_locations:
           get_locations["DbIpCity"] = none_location
        if "HostIP"not in get_locations:
           get_locations["HostIP"] = none_location
        if "Ip2location"not in get_locations:
           get_locations["Ip2location"] = none_location
        if "Ipstack"not in get_locations:
           get_locations["Ipstack"] = none_location
        if "MaxMind_GeoLite2City"not in get_locations:
           get_locations["MaxMind_GeoLite2City"] = none_location

        if "Eurek" not in get_locations:
           get_locations["Eurek"] = none_location   
        if "GeobytesCityDetails" not in get_locations:
           get_locations["GeobytesCityDetails"] = none_location
        if "IP_Info" not in get_locations:
           get_locations["IP_Info"] = none_location
        if "DbIpWeb" not in get_locations:
           get_locations["DbIpWeb"] = none_location
        if "IP2Location_Web" not in get_locations:
           get_locations["IP2Location_Web"] = none_location
        if "MaxMindGeoIp2City" not in get_locations:
           get_locations["MaxMindGeoIp2City"] = none_location
        if "NeustarWeb" not in get_locations:
           get_locations["NeustarWeb"] = none_location
        if "Skyhook" not in get_locations:
           get_locations["Skyhook"] = none_location

        if calculated is None:
            tqdm.write("Not enough locations fonud!")
            continue

        if "Average" not in calculated:
            calculated["Average"] = none_location
        if "Median" not in calculated:
            calculated["Median"] = none_location
        if "Clustering" not in calculated:
            calculated["Clustering"] = none_location
        
        try:
            csv_writer.writerow([ip, original_latitude, original_longitude,
                                 get_locations["DbIpCity"].latitude, get_locations["DbIpCity"].longitude,
                                 get_locations["HostIP"].latitude, get_locations["HostIP"].longitude,
                                 get_locations["Ip2location"].latitude, get_locations["Ip2location"].longitude,
                                 get_locations["Ipstack"].latitude, get_locations["Ipstack"].longitude,
                                 get_locations["MaxMind_GeoLite2City"].latitude, get_locations["MaxMind_GeoLite2City"].longitude,
                                 get_locations["Eurek"].latitude, get_locations["Eurek"].longitude,
                                 get_locations["GeobytesCityDetails"].latitude, get_locations["GeobytesCityDetails"].longitude,
                                 get_locations["IP_Info"].latitude, get_locations["IP_Info"].longitude,
                                 get_locations["DbIpWeb"].latitude, get_locations["DbIpWeb"].longitude,
                                 get_locations["IP2Location_Web"].latitude, get_locations["IP2Location_Web"].longitude,
                                 get_locations["MaxMindGeoIp2City"].latitude,get_locations["MaxMindGeoIp2City"].longitude,
                                 get_locations["NeustarWeb"].latitude, get_locations["NeustarWeb"].longitude,
                                 get_locations["Skyhook"].latitude, get_locations["Skyhook"].longitude,
                                 calculated["Average"].latitude, calculated["Average"].longitude,
                                 calculated["Median"].latitude, calculated["Median"].longitude,
                                 calculated["Clustering"].latitude, calculated["Clustering"].longitude])
            probes.remove(probe)
        except TypeError:
            tqdm.write("Calculation failed!")
            continue

with open("uncalculated_probes.json", 'w') as f:
    json.dump(probes, f)

