#!/usr/bin/env python3

"""
This example configures CSP on the host machine and establishes a CSP route to
the DUT via CAN, and the connection is verified by pinging the DUT. The
cmp_clock_set CSP command is then used to configure the time on the DUT.

Refer to lib/csp/src/bindings/python/pycsp.c for a complete list of available
csp 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 CAN,
the routing table below routes traffic to all nodes via CAN.

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

import argparse
import time
import datetime

import csp


def example(args):
    if args.dut == 'ais':
        from satlab import polaris_ais_client
        dut_addr = polaris_ais_client.DEFAULT_ADDRESS  # 20
        client = polaris_ais_client.PolarisAIS()
    elif args.dut == 'adsb':
        from satlab import polaris_adsb_client
        dut_addr = polaris_adsb_client.DEFAULT_ADDRESS  # 23
        client = polaris_adsb_client.PolarisADSB()
    elif args.dut == 'srs3':
        from satlab import srs3_client
        dut_addr = srs3_client.DEFAULT_ADDRESS  # 21
        client = srs3_client.SRS3()
    elif args.dut == 'srs4':
        from satlab import srs4_client
        dut_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.can_socketcan_init(args.can_device, args.can_rate)
    csp.route_start_task()
    # Route all packets to DUT via CAN
    csp.rtable_set(0, 0, 'CAN')

    print(f'CSP ping RTT: {client.csp.ping()}')

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


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

    parser.add_argument('--dut', help='Target DUT', type=str, choices=['ais', 'adsb', 'srs3', 'srs4'], required=True)
    parser.add_argument('--can-device', help='Name of CAN device on host PC', type=str, default='can0')
    parser.add_argument('--can-rate', help='Data rate of the CAN device, should match sys.can.rate on DUT',
                        type=int, default=1000000)

    args = parser.parse_args()

    example(args)


if __name__ == '__main__':
    main()
