#!/usr/bin/env python
#
# Copyright (c) 2017-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# LicenseRef-NvidiaProprietary
#
# NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
# property and proprietary rights in and to this material, related
# documentation and any modifications thereto. Any use, reproduction,
# disclosure or distribution of this material and related documentation
# without an express license agreement from NVIDIA CORPORATION or
# its affiliates is strictly prohibited
#

import sys
import errno
import argparse

from python_sdk_api.sx_api import *

def get_handle():
    rc, handle = sx_api_open(None)
    print ("sx_api_open handle:0x%x , rc %d " % (handle, rc))
    if (rc != SX_STATUS_SUCCESS):
        sys.stderr.write("Failed to open api handle.\nPlease check that SDK is running.")
        sys.exit(errno.EACCES)
    return handle

def tele_init():
    " This function init tele. "

    tele_param_p = new_sx_tele_init_params_t_p()
    handle = get_handle()
    output = sx_api_tele_init_set(handle, tele_param_p)
    sx_api_close(handle)
    return output


def tele_deinit():
    " This function deinit tele. "

    handle = get_handle()
    output = sx_api_tele_deinit_set(handle)
    sx_api_close(handle)
    return output


def tele_threshold_set(cmd, port, tc, th_type, threshold_hi, threshold_lo):
    " This function sets a threshold on the port and enables/disables the TC. "

    threshold_type = SX_TELE_THRESHOLD_TYPE_LATENCY_PORT_TC_E if th_type == 'latency' else SX_TELE_THRESHOLD_TYPE_PORT_TC_E
    key = sx_tele_threshold_key_t()
    key.key_type = threshold_type

    key_attr = sx_tele_threshold_port_tc_key_t()
    key_attr.log_port = port
    key_attr.tc = tc
    key.key.port_tc = key_attr

    data = sx_tele_threshold_data_t()
    data.threshold_data_type = SX_TELE_THRESHOLD_DATA_TYPE_LATENCY_E if th_type == 'latency' else SX_TELE_THRESHOLD_DATA_TYPE_PERCENTAGE_E
    data.threshold_data.threshold_high = threshold_hi
    data.threshold_data.threshold_low = threshold_lo

    handle = get_handle()
    rc = sx_api_tele_threshold_set(handle, cmd, key, data)
    sx_api_close(handle)
    print "sx_api_tele_threshold_set rc: %d " % (rc)
    return rc

def tele_threshold_get(cmd, port, tc, th_type):
    " This function gets the threshold of the port. "

    key = sx_tele_threshold_key_t()
    key.key_type = SX_TELE_THRESHOLD_TYPE_LATENCY_PORT_TC_E if th_type == 'latency' else SX_TELE_THRESHOLD_TYPE_PORT_TC_E
    key.key.port_tc.log_port = port
    key.key.port_tc.tc = tc

    data_p = new_sx_tele_threshold_data_t_p()

    handle = get_handle()
    rc = sx_api_tele_threshold_get(handle, SX_ACCESS_CMD_GET, key, data_p)
    sx_api_close(handle)
    print "sx_api_tele_threshold_get rc: %d " % (rc)

    data = sx_tele_threshold_data_t_p_value(data_p)
    print 'Data Type: {}'.format(data.data_type)
    print 'Threshold: port_tc_threshold {}'.format(data.data.port_tc_threshold)
    print 'Threshold: latency threshold high {}'.format(data.threshold_data.threshold_high)
    print 'Threshold: latency threshold low {}'.format(data.threshold_data.threshold_low)

    return data, rc


def setup_arg_parser():
    cfg = argparse.ArgumentParser()
    cfg.add_argument('--init', help='initialize telemetry module', dest='init', default=False, action='store_true')
    cfg.add_argument('--deinit', help='deinitialize telemetry module', dest='deinit', default=False, action='store_true')
    cfg.add_argument('--port', help='lid of the port')
    cfg.add_argument('--clear', help='set or clear', dest='clear', default=False, action='store_true')
    cfg.add_argument('--get', help='get', dest='get', default=False, action='store_true')
    cfg.add_argument('--update', help='update', dest='update', default=False, action='store_true')
    cfg.add_argument('--tc', help='traffic class 0-7', type=int, choices=range(0,8))
    cfg.add_argument('--type', help='latency or congestion', dest='th_type', choices=('latency', 'congestion'))
    cfg.add_argument('--threshold_hi', help='threshold hi', type=int)
    cfg.add_argument('--threshold_lo', help='threshold lo', type=int)
    return cfg


def main(args):

    parser = setup_arg_parser()
    cfgs = parser.parse_args(args)

    if cfgs.init:
        tele_init()
        sys.exit(0)

    if cfgs.deinit:
        tele_deinit()
        sys.exit(0)

    try:
        port_id = int(cfgs.port, 16)
    except:
        print 'port id invalid'
        sys.exit(1)


    if cfgs.clear:
        cmd = SX_ACCESS_CMD_DESTROY
    elif cfgs.get:
        cmd = SX_ACCESS_CMD_GET
    elif cfgs.update:
        cmd = SX_ACCESS_CMD_EDIT
    else:
        cmd = SX_ACCESS_CMD_SET

    if cmd == SX_ACCESS_CMD_GET:
        rc = tele_threshold_get(cmd=cmd,
                                port=port_id,
                                tc=cfgs.tc,
                                th_type=cfgs.th_type)
    else:
        rc = tele_threshold_set(cmd=cmd,
                                port=port_id,
                                tc=cfgs.tc,
                                th_type=cfgs.th_type,
                                threshold_hi=cfgs.threshold_hi,
                                threshold_lo=cfgs.threshold_lo)

if __name__ == '__main__':
    rc = 1
    try:
        rc = main(sys.argv[1:])
    except Exception as e:
        sys.stderr.write(str(e))
    sys.exit(rc)
