#!/usr/bin/env python3

"""
This example configures CSP on the host machine and establishes a CSP route to
a SRS-x via KISS. SRS specific bindings are then demonstrated.

Refer to client/srs3/python/bindings/srs3_client_python.c and
client/srs4/python/bindings/srs4_client_python.c for a complete list of
available srs bindings and the function docstrings for more information about a
specific function.

Prerequisites:

Python bindings shall be enabled when building ``satctl`` and installed on the
system or in a virtual environment. See the ``README`` file for details.

The routing table on the DUT shall be configured to respond to node 5 via KISS,
the routing table below routes traffic to node 5 via KISS, and traffic to all
other nodes via CAN.

    [srs] prop list sys
    Property        Type  Stat  Flag  Value
    ...
    csp.routes      str   B     -     0/0 CAN, 5/5 KISS
    ...
"""

import time
import datetime
import argparse

import csp


def example(args):
    if args.dut == 'srs3':
        from satlab import srs3_client
        srs_addr = srs3_client.DEFAULT_ADDRESS  # 21
        client = srs3_client.SRS3()
    elif args.dut == 'srs4':
        from satlab import srs4_client
        srs_addr = srs4_client.DEFAULT_ADDRESS  # 24
        client = srs4_client.SRS4()
    else:
        raise NotImplementedError(f"DUT {args.dut} not supported")

    host_csp_addr = 5

    csp.init(host_csp_addr)

    csp.kiss_init(args.kiss_device, args.kiss_rate)
    csp.route_start_task()
    # Route all packets to SRS via KISS
    csp.rtable_set(srs_addr, 5, 'KISS')

    # Set time on SRS to own time
    sec = time.time()
    csp.cmp_clock_set(srs_addr, int(sec), round((sec - int(sec)) * 1e9))
    now = csp.cmp_clock_get(srs_addr)
    print(f'Time set to {datetime.datetime.fromtimestamp(now[0] + now[1] / 1e9)} UTC')

    # Read and reset the ground watchdog timer (GWDT)
    gwdt_before_sleep = client.gwdt_counter()
    print(f"GWDT before sleep {gwdt_before_sleep}")
    time.sleep(3)
    gwdt_after_sleep = client.gwdt_counter()
    print(f"GWDT val after sleep {gwdt_after_sleep}")
    assert gwdt_before_sleep > gwdt_after_sleep
    # Resetting the timer should set it to 24 hours (86400 seconds)
    client.gwdt_reset()
    time.sleep(1)
    gwdt_after_reset = client.gwdt_counter()
    print(f"Counter val after reset {gwdt_after_reset}")
    assert gwdt_after_reset > gwdt_before_sleep


def main():
    # Parse arguments
    parser = argparse.ArgumentParser()

    parser.add_argument('--dut', help='Target DUT', type=str, choices=['srs3', 'srs4'], required=True)
    parser.add_argument('--kiss-device', help='Path to KISS device on host PC', type=str, default='/dev/ttyUSB1')
    parser.add_argument(
        '--kiss-rate', help='Data rate of the KISS device, must match sys.uart.rate on DUT', type=int, default=3000000)

    args = parser.parse_args()

    example(args)


if __name__ == '__main__':
    main()
