#!/bin/env python3

import datetime
import requests
import time
import os
import argparse # Import the argparse module

# --- Argument Parsing ---
parser = argparse.ArgumentParser(
    description="Monitor temperature from a specified IP and port.",
    formatter_class=argparse.ArgumentDefaultsHelpFormatter,
    )
parser.add_argument(
    '-i', '--ip',
    type=str,
    default="172.16.31.1",
    help="The IP address of the device to monitor (default: 172.16.31.1)"
)
parser.add_argument(
    '-p', '--port',
    type=str, # Keep as string as it's part of a URL string, though int could also work
    default="8080",
    help="The port number of the device to monitor"
)
parser.add_argument(
    '-s', '--sleep_time',
    type=float,
    default=10,
    help="The time in seconds to wait between requests"
)
parser.add_argument(
    '--utc_offset',
    type=float,
    default=18,
    help="The time in seconds between UTC and GPS seconds (18s as of 2025)."
)
parser.add_argument(
    '-q', '--quiet',
    action='store_true', # This makes it a boolean flag; if present, args.quiet will be True
    help="Suppress output to the console (data will still be written to the log file)"
)
args = parser.parse_args()

FMT = '%Y-%m-%d_%H-%M-%S'
fname_log = f"monitor_mode_{datetime.datetime.now().strftime(FMT)}.log"

# Function to print to console if not in quiet mode, and always write to file
def log_and_print(message, log_file_handle, quiet_mode):
    if not quiet_mode:
        print(message)
    log_file_handle.write(message + "\n")

# Define the GPS epoch (January 6, 1980, 00:00:00 UTC)
GPS_EPOCH = datetime.datetime(1980, 1, 6, 0, 0, 0, tzinfo=datetime.timezone.utc)


# Function to compute GPS week and seconds from a UTC datetime object
def get_gps_time(utc_datetime, offset=18):
    # Ensure the input datetime is UTC
    if utc_datetime.tzinfo is None:
        utc_datetime = utc_datetime.replace(tzinfo=datetime.timezone.utc)
    utc_datetime = utc_datetime + datetime.timedelta(seconds=offset)
    

    # Calculate the time difference from the GPS epoch
    time_difference = utc_datetime - GPS_EPOCH

    # Total seconds since GPS epoch
    total_seconds = int(time_difference.total_seconds())

    # GPS week (integer division)
    gps_week = total_seconds // (7 * 24 * 3600)

    # GPS seconds within the current week (modulo)
    gps_seconds = total_seconds % (7 * 24 * 3600)

    return gps_week, gps_seconds


with open(fname_log, 'a') as f:
    log_and_print(f"fname_log: {fname_log}", f, False)
    log_and_print(f"ip: {args.ip}", f, False)
    log_and_print(f"port: {args.port}", f, False)
    log_and_print(f"sleep_time: {args.sleep_time}", f, False)
    log_and_print(f"quiet_mode: {args.quiet}", f, False)

# Main loop to continuously fetch and log data
while True:
    try:
        # Get UTC and local timestamps
        utc_time = datetime.datetime.utcnow().strftime(FMT)
        local_time = datetime.datetime.now().strftime(FMT)
        current_utc_datetime = datetime.datetime.utcnow()
        gps_week, gps_seconds = get_gps_time(current_utc_datetime)

        # Construct the URL using the (now potentially dynamic) ip and port
        url = f"http://{args.ip}:{args.port}/prog/show?temperature"

        # Fetch data using requests
        response = requests.get(url, timeout=5) # Added a timeout for robustness
        response.raise_for_status() # Raise an HTTPError for bad responses (4xx or 5xx)
        temperature_data = response.text.strip()

        # Format the log entry
        #log_entry = f"utc:{utc_time} local:{local_time} {temperature_data}"
        log_entry = (
            f"utc:{utc_time} "
            f"gps_week:{gps_week} gps_seconds:{gps_seconds} "
            f"local:{local_time} "
            f"{temperature_data}"
        )


        # Print to console and log to file
        with open(fname_log, 'a') as f:
            log_and_print(log_entry, f, args.quiet)

    except requests.exceptions.RequestException as e:
        # Handle network-related errors (e.g., connection refused, timeout)
        error_message = f"utc:{utc_time} ERROR fetching data: {e}"
        with open(fname_log, 'a') as f:
            log_and_print(error_message, f, args.quiet)
    except Exception as e:
        # Handle any other unexpected errors
        general_error_message = f"utc:{utc_time} ERROR An unexpected error occurred: {e}"
        with open(fname_log, 'a') as f:
            log_and_print(general_error_message, f, args.quiet)

    # Wait for the specified sleep_time before the next iteration
    time.sleep(args.sleep_time)

