/*
 * Copyright (c) 2007 Endace Technology Ltd, Hamilton, New Zealand.
 * All rights reserved.
 *
 * This source code is proprietary to Endace Technology Limited and no part
 * of it may be redistributed, published or disclosed except as outlined in
 * the written contract supplied with this product.
 *
 * $Id: attribute_print.c 14133 2011-04-08 04:54:59Z karthik.sharma $
 */

#include "dag_config.h"
#include "dag_attribute_codes.h"
#include "dag_component_codes.h"
#include "dag_component.h"
#include "attribute_print.h"
#include <stdio.h>
#include <assert.h>

#define MAX_FIELD_WIDTH 20 /* printed length of the widest decimal number (uint64) */

static unsigned int get_attribute_width(dag_card_ref_t card, attr_uuid_t attr) ;

static unsigned int 
get_attribute_width(dag_card_ref_t card, attr_uuid_t attr) 
{
	dag_attr_t type;
    unsigned int width, value_width = 1, name_width;
    char buffer[MAX_FIELD_WIDTH + 1];

    /* it would be more efficient to use the mask size to determine
     * the printout size, but mask is private to the attribute, so we
     * have to use the valuetype instead */

    /* determine the size of the value */
	type = dag_config_get_attribute_valuetype(card, attr);
    switch (type) {
    case kAttributeBoolean:
        value_width = 1; /* 0 or 1 */
        break;
    case kAttributeChar:
        value_width = 4; /* -128 .. 127 */
        break;
    case kAttributeInt32:
    case kAttributeUint32:
        value_width = 10; /* [0..4,294,967,296]  or [-134,217,728..134,217,727] */
        break;
    case kAttributeInt64:
    case kAttributeUint64:
        value_width = 20; /* [0..18,446,744,073,709,551,616] or [-9,223,372,036,854,775,808..9,223,372,036,854,775,807] */
        break;
    case kAttributeString:
        value_width = strlen ( dag_config_get_string_attribute(card, attr));
        break;
    default:
        /* For other attributes assume the width is 10 */
        value_width = 10;
    }

    /* determine the size of the name */
    name_width = snprintf(buffer, sizeof(buffer), "%s",dag_config_get_attribute_name(attr));
    width = value_width > name_width ? value_width : name_width;
    return width;
}
/**
 * For header formatting determine the width of the attribute's name
 * and the possible maximum width of its value - use whichever is
 * greater.
 */
unsigned int
attribute_print_header(dag_card_ref_t card, attr_uuid_t attr)
{
	dag_attribute_code_t code;
    unsigned int width;

	code = dag_config_get_attribute_code(attr);
    if (code == kAttributeInvalid) {
        /* add code to handle exceptional attributes - the above is just a dummy */
	assert(0);
    }

    width = get_attribute_width(card, attr);
    printf(" %*.*s ", width, width, dag_config_get_attribute_name(attr));
    return width;
}

void
attribute_print_value(dag_card_ref_t card, attr_uuid_t attr, dag_config_state_t state,int component_index)
{
	dag_attr_t type;
	dag_attribute_code_t code;
    	const char* string;
    	char number[40];
    	unsigned int width = 0;
	line_rate_t line_rate = kLineRateInvalid;
	dag_component_t root_component = NULL;
	dag_component_t comp = NULL;
        dag_component_t port_component = NULL;
        dag_component_t phy_component = NULL;
	attr_uuid_t line_rate_attr = kNullAttributeUuid;
	root_component = dag_config_get_root_component(card);
        port_component = dag_component_get_subcomponent(root_component, kComponentPort, component_index);
        phy_component = dag_component_get_subcomponent(root_component, kComponentPhy, component_index);
	line_rate_attr = dag_component_get_attribute_uuid( port_component, kUint32AttributeLineRate);
	if(kNullAttributeUuid == line_rate_attr)
	{
		line_rate_attr = dag_component_get_attribute_uuid( phy_component, kUint32AttributeLineRate);
	}
	line_rate = dag_config_get_uint32_attribute(card, line_rate_attr);	
	code = dag_config_get_attribute_code(attr);

    	if (code == kAttributeInvalid) {
        	/* add code to handle exceptional attributes - the above is just a dummy */
        	string = dag_config_get_attribute_to_string(card, attr);
        	printf("     %s ", string);
    	} 
	else if (code == kBooleanAttributeLink)
	{
		width = get_attribute_width(card, attr);
		if(line_rate == kLineRateOC192c)
		{
			snprintf(number, 40, "-");
		}
		else
		{
			snprintf(number, 40, "%hhd", dag_config_get_boolean_attribute(card, attr));
		}
        	printf(" %*s ", width, number);
	}
	else if ((code == kBooleanAttributeLossOfPointer) || (code == kBooleanAttributeLossOfFrame))
	{
		width = get_attribute_width(card, attr);
		comp = dag_config_get_component_from_attribute(card,attr);
		if(((line_rate == kLineRateWAN))&& ((kComponentPort == dag_config_get_component_code(comp))))
		{
			/*This case is applicable to Dag 9.2x2 wan mode.*/
			snprintf(number, 40, "%hhd", dag_config_get_boolean_attribute(card, attr));
		}
		else if (((line_rate == kLineRateSTM0) || (line_rate == kLineRateSTM1)|| (line_rate == kLineRateSTM4) || (line_rate == kLineRateSTM16) || (line_rate == kLineRateSTM64)||(line_rate == kLineRateOC192c) || (line_rate == kLineRateOC48c) || (line_rate == kLineRateOC12c) || (line_rate == kLineRateOC3c) || (line_rate == kLineRateOC1c)) && (kComponentSonetPP == dag_config_get_component_code(comp)))
		{
			snprintf(number, 40, "%hhd", dag_config_get_boolean_attribute(card, attr));
		}
		else if ((line_rate == kLineRateWAN) && (kComponentSonetPP == dag_config_get_component_code(comp)))
                {       /*This case is applicable to wan mode of Dag 8.1sx and Dag 9.2sx2.*/
                       snprintf(number, 40, "%hhd", dag_config_get_boolean_attribute(card, attr));

                }
                else if (((line_rate == kLineRateSTM0) || (line_rate == kLineRateSTM1)|| (line_rate == kLineRateSTM4) || (line_rate == kLineRateSTM16) || (line_rate == kLineRateSTM64) || (line_rate == kLineRateOC192c) || (line_rate == kLineRateOC48c) || (line_rate == kLineRateOC12c) || (line_rate == kLineRateOC3c) || (line_rate == kLineRateOC1c)) && (kComponentPort == dag_config_get_component_code(comp)))
                {
                       snprintf(number, 40, "%hhd", dag_config_get_boolean_attribute(card, attr));
                }
		else if (((line_rate == kLineRateEthernet1000) || (line_rate == kLineRateEthernet100) || (line_rate == kLineRateEthernet10)) && ((kComponentMiniMac == dag_config_get_component_code(comp)) || (kComponentPort == dag_config_get_component_code(comp))))
		{
			/*the two attributes are registered as loss_of_frame and loss_of_pointer respectively in QT2225 framer whereas in Minimac it is registered as lof and lop.*/
			if((0 == strncmp(dag_config_get_attribute_name(attr),"loss_of_frame",(strlen("loss_of_frame")))) || ((0 == strncmp(dag_config_get_attribute_name(attr),"loss_of_pointer",(strlen("loss_of_pointer"))))))
			{
				snprintf(number, 40, "-");
			}
			else
			{
				snprintf(number, 40, "%hhd", dag_config_get_boolean_attribute(card, attr));
			}
		}
		else
		{
			snprintf(number, 40, "-");
		}
        	printf(" %*s ", width, number);
	}
	else 
	{
        	width = get_attribute_width(card, attr);
        	if ( kStateActive != state )
		{
        		snprintf(number, 40, "-");
        	}
        	else 
		{ 
            		type = dag_config_get_attribute_valuetype(card, attr);
            		switch (type) 
			{
            		case kAttributeBoolean:
               	 			snprintf(number, 40, "%hhd", dag_config_get_boolean_attribute(card, attr));
                			break;
            		case kAttributeChar:
    			//            snprintf(number, 40, "%hhd", dag_config_get_char_attribute(card, attr));
    			//            break;
            		case kAttributeInt32:
			//            snprintf(number, 40, "%d", dag_config_get_int32_attribute(card, attr));
		    	//            break;	
	            	case kAttributeUint32:
		    	//            snprintf(number, 40, "%u", dag_config_get_uint32_attribute(card, attr));
			//            break;
	            	case kAttributeInt64:
			//            snprintf(number, 40, "%"PRId64, dag_config_get_int64_attribute(card, attr));
			//            break;
	            	case kAttributeUint64:
		    	//            snprintf(number, 40, "%"PRIu64, dag_config_get_uint64_attribute(card, attr));
		    	//            break;
		        case kAttributeString:
			//            snprintf(number, 40, "%s", dag_config_get_string_attribute(card, attr));
		    	//            break;
		        default:
                		/* Use the string conversion function*/
                		snprintf( number,40,"%s",dag_config_get_attribute_to_string(card,attr));
            		}
		}
        	printf(" %*s ", width, number);
	}
}
