AUTHOR
FIREWHEEL Team
DONE
DESCRIPTION
Get the time (in UTC) of when the experiment will start
(i.e. when experiment positive time will start). To get the
time in UTC on your control/compute nodes (to compare) you can
use the command ``date --utc``.

If the experiment has started, the number of seconds since the experiment
started is also printed.

This Helper supports both human-readable text output and machine-readable
JSON output.

Arguments
+++++++++
All arguments are optional.

Named Arguments
^^^^^^^^^^^^^^^

.. option:: -h, --help

    Show help message and exit.

.. option:: --format {text,json}

    :default: ``text``

    Select the output format. ``text`` prints a human-readable summary.
    ``json`` returns a structured JSON response.

.. option:: --json

    Backward-compatible alias for ``--format json``.

Example
+++++++

``firewheel time``

``firewheel time --format json``

DONE
RUN LocalPython ON control
#!/usr/bin/env python

import json
import argparse
from datetime import datetime, timezone

from rich.console import Console

import firewheel.vm_resource_manager.api as vm_resource_api


def collect_time_data():
    """
    Collect experiment time information.

    Returns:
        dict: Structured experiment time data.
    """
    experiment_time = vm_resource_api.get_experiment_start_time()
    seconds_since_start = vm_resource_api.get_experiment_time_since_start()

    start_time_iso = None
    start_time_display = None
    experiment_time_known = experiment_time is not None
    experiment_started = False
    message = "Experiment start time not yet determined."

    if experiment_time is not None:
        experiment_time_utc = experiment_time.astimezone(timezone.utc)
        start_time_iso = experiment_time_utc.isoformat()
        start_time_display = experiment_time_utc.strftime("%m-%d-%Y %H:%M:%S UTC")

    if seconds_since_start is not None:
        seconds_since_start = int(seconds_since_start)
        experiment_started = seconds_since_start > 0

        if seconds_since_start > 0:
            message = f"Experiment started {seconds_since_start} seconds ago"
        else:
            message = f"Experiment will start in {abs(seconds_since_start)} seconds"
    elif experiment_time is not None:
        message = "Experiment start time determined, but elapsed time is not available."

    return {
        "start_time": start_time_iso,
        "start_time_display": start_time_display,
        "seconds_since_start": seconds_since_start,
        "experiment_time_known": experiment_time_known,
        "experiment_started": experiment_started,
        "message": message,
        "generated_at": datetime.now(timezone.utc).isoformat(),
    }


def render_text(time_data):
    """
    Render human-readable experiment time output using Rich.
    """
    console = Console()

    if time_data["start_time_display"] is not None:
        console.print(
            f"[green]Experiment start time:[/green] "
            f"[cyan]{time_data['start_time_display']}[/cyan]"
        )

    if time_data["seconds_since_start"] is not None:
        if time_data["seconds_since_start"] > 0:
            console.print(f"[green]{time_data['message']}[/green]")
        else:
            console.print(f"[yellow]{time_data['message']}[/yellow]")
    elif time_data["start_time_display"] is None:
        console.print("[yellow]Experiment start time not yet determined.[/yellow]")
    else:
        console.print(f"[yellow]{time_data['message']}[/yellow]")


def render_json(time_data):
    """
    Render machine-readable JSON output.
    """
    json_data = dict(time_data)
    json_data.pop("start_time_display", None)
    print(json.dumps(json_data, indent=2))


def main():
    """
    Parse command-line arguments and display experiment time information.
    """
    parser = argparse.ArgumentParser(
        description="FIREWHEEL Experiment Start Time",
        prog="firewheel time",
    )
    parser.add_argument(
        "--format",
        choices=["text", "json"],
        default="text",
        help="Output format. Defaults to text.",
    )
    parser.add_argument(
        "--json",
        action="store_true",
        default=False,
        help=argparse.SUPPRESS,
    )

    args = parser.parse_args()

    if args.json:
        args.format = "json"

    time_data = collect_time_data()

    if args.format == "json":
        render_json(time_data)
    else:
        render_text(time_data)


if __name__ == "__main__":
    main()
DONE
