#!/var/www/html/api/v1/lib/venv/bin/python
import json
import os
import glob
import argparse
from ping3 import ping
import requests

CONFIG = {}

# ["172.219.31.73", 8333, 70016, "/Satoshi:24.0.1/", 1687438350, 1033, 795846, "d172-219-31-73.abhsia.telus.net", "Edmonton", "CA", 53.5417, -113.5005, "America/Edmonton", "AS852", "TELUS Communications"]

def get_nodes(path):
    """
    Returns all reachable nodes from a JSON file.
    """
    nodes = []
    text = open(path, 'r').read()
    try:
        nodes = json.loads(text)
    except ValueError as err:
        print(err)
    return nodes


def check_node_status_and_speed(address, port, timeout=1000, count=5):
    ping_results = []
    address = "128.65.194.136"
    for _ in range(count):
        result = ping(address, timeout=timeout / 1000, unit='ms', src_addr = '0.0.0.0', size=64)
        if result is not None:
            ping_results.append(result)
    if len(ping_results) > 0:
        average_latency = sum(ping_results) / len(ping_results)
        speed_bps =  (64 *8 * 2 ) / (average_latency / 1000.0 )  # Convert latency to speed in Mbps
        # print(speed_bps)
        speed_mbps = speed_bps / 1000

        

        if average_latency > 0:
            status = "REACHABLE"
        else:
            status = "UNREACHABLE"

        return status, speed_mbps
    else:
        return None, None
    
def get_nodestatus(address, port):

    # Define the file directory and path
    f_dir = CONFIG["CRAWLER_EXPORT_DIR"]
    fpath = max(glob.iglob(f'{f_dir}*.json'))
    timestamp = os.path.basename(fpath).removesuffix(".json")

    result = {}
    result["address"]  = address
    result["status"]  = None
    result["mbps"]  = None
    result["data"] = None
    try:
        result["status"], result["mbps"] = check_node_status_and_speed(address, port, timeout=1000, count=5)
        with open(fpath, 'r') as file:
            # Load the contents of the file
            data = json.load(file)


            for item in data:
                # Node lookup in Json file
                if address == item[0]:
                    if port == item[1]:
                        # Check if item has the correct length
                        if len(item) != 15:
                            result["error"] = "Incorrect item length"
                            return json.dumps(result), 400
                        
                        # Individual fields from the item array
                        # Ip_Address, Port, Protocol_version, User_agent, Connected_since, Services, Height, Hostname, City, Country_code, Latitude, Longitude, Timezone, ASN, Organization_name = item

                        # Store relevant information in the data array
                        result["data"] = item[2:]
                        return json.dumps(result), 200

    except FileNotFoundError:
        result["error"] = "File not found"
        return json.dumps(result), 404

    return json.dumps(result), 200



# def get_nodestatus(address, port):
#     try:
#         # Define the file directory and path
#         f_dir = CONFIG["CRAWLER_EXPORT_DIR"]
#         fpath_crawl = max(glob.iglob(f"{CONFIG['CRAWLER_CRAWL_DIR']}/*.json"))
#         fpath_export = max(glob.iglob(f"{CONFIG['CRAWLER_EXPORT_DIR']}/*.json"))
#         nodes = get_nodes(fpath_crawl)

#         address = None
#         port = 
#         for node in nodes:
#             address = node[0]
#             port = node[1]
#             services = node[2]
#             height = node[3]

#         # Get a list of JSON files in the directory
#         f_list = glob.glob(f'{f_dir}*.json')
#         f_list.sort(reverse=True)

#         # Validate the limit parameter type
#         if not isinstance(limit, int):
#             raise TypeError("Limit must be an integer")

#         # Validate the page parameter type
#         if not isinstance(page, int):
#             raise TypeError("Page must be an integer")

#         # Calculate the total number of pages
#         total_snapshots = len(f_list)
#         total_pages = (total_snapshots + limit - 1) // limit

#         # Validate the page parameter
#         if page < 1 or page > total_pages:
#             raise ValueError("Invalid page number")

#         # Calculate the start and end indices for the current page
#         start_index = (page - 1) * limit
#         end_index = start_index + limit

#         # Create a list of snapshot results for the current page
#         results = []
#         for fpath in f_list[start_index:end_index]:
#             entry = {}
#             entry["timestamp"] = os.path.basename(fpath).removesuffix(".json")
#             entry["url"] = CONFIG["API_BASE_URL"] + f"snapshots.php?timestamp={entry['timestamp']}"

#             with open(fpath, 'r') as file:
#                 data = json.load(file)
#                 entry["total_nodes"] = len(data)
#                 entry["latest_height"] = data[-1][6]

#             results.append(entry)

#         # Create the API response dictionary
#         response = {
#             "count": total_snapshots,
#             "results": results
#         }

#         # Add the "next" field to the response if there is a next page
#         if page < total_pages:
#             next_page = page + 1
#             next_limit = "" if limit <= 10 else f"&limit={limit}"
#             response["next"] = CONFIG["API_BASE_URL"] + f"/snapshots/?page={next_page}{next_limit}"
#             # print(limit)
#         else:
#             response["next"] = None

#         # Add the "previous" field to the response if there is a previous page
#         if page > 1:
#             previous_page = page - 1
#             previous_limit = "" if limit <= 10 else f"&limit={limit}"
#             response["previous"] = CONFIG["API_BASE_URL"] + f"/snapshots/?page={previous_page}{previous_limit}"
#         else:
#             response["previous"] = None

#         return json.dumps(response), 200

#     except TypeError as e:
#         error_response = {"error": str(e)}
#         return json.dumps(error_response), 400

#     except ValueError as e:
#         error_response = {"error": str(e)}
#         return json.dumps(error_response), 400

#     except Exception as e:
#         error_response = {"error": "An error occurred while processing the request"}
#         return json.dumps(error_response), 500

if __name__ == "__main__":
    with open("/var/www/html/api/v1/lib/config.json") as f:
        CONFIG = json.load(f)

    # Create an argument parser
    parser = argparse.ArgumentParser(description="API Manager")

    # Add the arguments
    parser.add_argument("--address", type=str, default=None, help="IP Address of node.")
    parser.add_argument("--port", type=int, default=None, help="The corresponding port number of the node's ip address.")

    # Parse the arguments
    args = parser.parse_args()

    # Call the get_snapshots function with the specified page and limit
    # print(f"   args.address", args.address)
    # print(f"   args.port--", args.port)
    response, status_code = get_nodestatus(args.address, args.port)
    print(response)

    # if (args.timestamp):
    #     # print("--get_snapshots_by_export_timestamp--")
    #     response, status_code = get_snapshots_by_export_timestamp(timestamp=args.timestamp, field=args.field)
    #     print(response)
    # else:
    #     # print("--get_snapshots-")
    #     response, status_code = get_snapshots(limit=args.limit, page=args.page)
    #     print(response)
