/*
 * Copyright (c) 2005-2006 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.
 *
 */

/* For printing card counters*/
#include "extended_statistics_printing.h"
#include "counter_printing.h"
#include "statistics_printing.h"
#include "attribute_print.h"
#include "configuration_printing.h"
#include "../../include/dag_config.h"
#include "../../include/dag_attribute_codes.h"
#include "../../include/dag_component_codes.h"
#include "../../include/dag_component.h"
#include "dagutil.h"
#include <stdio.h>
#include <assert.h>

static attribute_verbosity_mapping_t ext_attr_verbose_array[] =
{
	{kUint32AttributeRxFrames, 0},
    {kUint64AttributeRxFrames, 0},
	{kUint64AttributeRxBytes, 0},
    {kUint32AttributeRxBytes, 0},
 	{kUint32AttributeTxFrames, 0},
    {kUint64AttributeTxFrames, 0},
    {kUint64AttributeTxBytes, 0},
    {kUint32AttributeTxBytes, 0},
    {kUint32AttributeCRCErrors, 0},
    {kUint32AttributeShortPacketErrors, 0},
	{kUint32AttributeLongPacketErrors, 0},
    {kUint32AttributeBadSymbols, 0},
    {kUint32AttributeB1ErrorCount, 0},
    {kUint32AttributeB2ErrorCount, 0 },
    {kUint32AttributeB3ErrorCount, 0},
    {kUint32AttributeREIErrorCount, 0},
    {kUint32AttributeJ0PathLabel, 1},
    {kUint32AttributeJ1PathLabel, 1},
    {kUint32AttributeC2PathLabel, 1},
    {kUint64AttributeRxBytesBad, 1}, 
    {kUint32AttributeRxParityError, 1},
    {kUint32AttributeRxByteCount, 0},
    {kUint32AttributeRxPacketCount,0},
    {kUint32AttributePacketRateReport, 0},
    /* dagconfig-ising dag43ge  */
    {kUint64AttributeBadSymbol, 0},
    {kUint64AttributeCRCFail, 0},
    /* dagconfig ising dag37t */
    {kUint32AttributeCableLoss, 0},
    {kUint32AttributeLossOfCellDelineationCount, 0},
    {kUint32AttributeDropCount, 0},
    {kUint32AttributeE1T1FramerCounter, 0},
    {kUint32AttributeE1T1CRCCounter, 0},
    {kUint32AttributeE1T1AISCounter, 0},
    {kUint32AttributeCounter1, 0},
    {kUint32AttributeCounter2, 0}
};

/* List of component codes to print statistics info for
 *
 * Some fimrware modules implement both the (de)framer and
 * (de)mapper and the component type can be any of those
 * below. Hopefully only one of them is present, otherwise we will
 * end up with multiple lines for each framer/mapper. */
dag_component_code_t ext_comp_codes[] = {
	kComponentPhy,
    kComponentPort,
    kComponentSonetPP,
    kComponentFramer,
    kComponentDeframer,
    kComponentMapper,
    kComponentDemapper,
    kComponentPCS,
    kComponentXGMII,
    kComponentXGMIIStatistics,
    kComponentInfiniBandFramer,
    kComponentMemTx,
    kComponentMiniMac
};
 
static void dag82x_print_tx_statistics_header(void);
static void dag82x_print_tx_statistics(dag_card_ref_t card, int port);
static void dag38_print_extended_statistic_header(dag_card_ref_t card, int port);
//static void dag50s_print_tx_statistics_header(void);
//static void dag50s_print_tx_statistics(dag_card_ref_t card, int port);

void dagx_print_extended_statistics_header(dag_card_ref_t card_ref);
void dagx_print_extended_statistics(dag_card_ref_t card_ref, int port);
static bool attribute_is_printable(dag_card_ref_t card_ref, attr_uuid_t attr);

void
print_extended_statistics_header(dag_card_ref_t card, ext_stat_t ext_stat_type)
{
    switch(dag_config_get_card_type(card))
    {
	case kDag38:
	    dag38_print_extended_statistic_header(card, 0);
            printf(" Port ");
            dag38_print_extended_statistic_header(card, 1); 
            break;
        case kDag452e:
        case kDag454e:
        case kDag452gf:            
        case kDag452cf:
        case kDag452z:
        case kDag452z8:
            dag45ge_print_extended_statistics_header(ext_stat_type);
            break;
        case kDag62:
            dag62se_print_extended_statistics_header(card);
            break;
        case kDag71s:
            dag71s_print_extended_statistics_header();
            break;
	case kDag52x:
	case kDag82x:
	case kDag82z:
	case kDag810:
//		dag82x_print_extended_statistics_header();
//		break;
//        case kDag50s:
//            dag52sxa_print_extended_statistics_header();
//            break;
        default:
            dagx_print_extended_statistics_header(card);
            break;
    }
}

void
print_extended_statistics(dag_card_ref_t card, int port, ext_stat_t ext_stat_type, int vc_index)
{
    switch(dag_config_get_card_type(card))
    {
        case kDag452e:
        case kDag454e:
        case kDag452gf:            
        case kDag452cf:
        case kDag452z:
        case kDag452z8:
            dag45ge_print_extended_statistics(card, port, ext_stat_type);
            break;
        case kDag62:
            dag62se_print_extended_statistics(card, port);
            break;
        case kDag71s:
            dag71s_print_extended_statistics(card, port, vc_index);
            break;
	case kDag52x:
	case kDag82x:
	case kDag82z:
	case kDag810:
//		dag82x_print_extended_statistics(card, port);
//		break;
//	case kDag50s:
//		dag52sxa_print_extended_statistics(card, port);
//		break;
				
        default:
            dagx_print_extended_statistics(card, port);
            break;
    }
                
}

void
print_tx_statistics_header(dag_card_ref_t card)
{
    switch (dag_config_get_card_type(card))
    {
        case kDag452e:
        case kDag454e:
        case kDag452gf:            
        case kDag452cf:
        case kDag452z:
        case kDag452z8:
            dag45ge_print_tx_statistics_header();
            break;
        case kDag52x:
        case kDag82x:
	case kDag82z:
	case kDag810:
            dag82x_print_tx_statistics_header();
            break;
//	case kDag50s:
//            dag50s_print_tx_statistics_header();
//            break;
        default:
            printf("printing of tx statistics for this card not supported\n");
            break;
    }
}

void
print_tx_statistics(dag_card_ref_t card, int port)
{
    switch (dag_config_get_card_type(card))
    {
        case kDag452e:
        case kDag454e:
        case kDag452gf:            
        case kDag452cf:
        case kDag452z:
        case kDag452z8:
            dag45ge_print_tx_statistics(card, port);
            break;
        case kDag52x:
        case kDag82x:
	case kDag82z:
	case kDag810:
            dag82x_print_tx_statistics(card, port);
            break;
//	case kDag50s:
//            dag50s_print_tx_statistics(card, port);
//            break;
        default:
            printf("printing of tx statistics for this card not supported\n");
            break;
    }
}
#if 0
void
dag82x_print_extended_statistics_header()
{
	dag82x_print_statistics_header();
	dag82x_print_counters_header();
}

void
dag82x_print_extended_statistics(dag_card_ref_t card, int port)
{
	dag82x_print_statistics(card, port);
	dag82x_print_counters(card, port);
}
#endif
void 
dag38_print_extended_statistic_header(dag_card_ref_t card, int port)
{
        attr_uuid_t any_attribute;
	dag_component_t root;
	dag_component_t comp;
	dag_attribute_code_t code;
	int attr_count = 0;
	int j = 0;
  
	root = dag_config_get_root_component(card);
        comp = dag_component_get_subcomponent(root, kComponentPort,port);

        attr_count = dag_component_get_attribute_count(comp);
        for (j = 0; j < attr_count; j++)
        {
                any_attribute = dag_component_get_indexed_attribute_uuid(comp, j);
                code = dag_config_get_attribute_code(any_attribute);
                if (attribute_is_printable(card, any_attribute))
                {
                    attribute_print_header(card, any_attribute);
                }
        }

}

void
dag71s_print_extended_statistics_header()
{
    printf("B1_Count  B2_Count  B3_Count  REI_Count  ");
}

void
dag71s_print_extended_statistics(dag_card_ref_t card_ref, int port, int vc_index)
{
    dag_component_t any_component;
    dag_component_t root_component;
    attr_uuid_t any_attribute;
    

    root_component = dag_config_get_root_component(card_ref);
    
    /* Read the Optics information */
    any_component = dag_component_get_subcomponent(root_component, kComponentSonic, port);

    /* Set the vc we want to use */
    any_attribute = dag_component_get_attribute_uuid(any_component, kUint32AttributeVCIndex);
    dag_config_set_uint32_attribute(card_ref, any_attribute, vc_index);

    /* Latch the counters */
    any_attribute = dag_component_get_attribute_uuid(any_component, kBooleanAttributeCounterLatch);
    assert(any_attribute != kNullAttributeUuid);
    dag_config_set_boolean_attribute(card_ref, any_attribute, 1);
    
    if(vc_index != 0)
    {
        printf("%8s  ", "..");
        printf("%8s  ", "..");
    }
    else
    {
        /* B1_Count */
        any_attribute = dag_component_get_attribute_uuid(any_component, kUint32AttributeB1ErrorCount);
        printf("%8u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));
        /* B2_Count */
        any_attribute = dag_component_get_attribute_uuid(any_component, kUint32AttributeB2ErrorCount);
        printf("%8u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));
    }

    /* B3_Count */
    any_attribute = dag_component_get_attribute_uuid(any_component, kUint32AttributeB3ErrorCount);
    printf("%8u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));
    /* REI_Count */
    any_attribute = dag_component_get_attribute_uuid(any_component, kUint32AttributeREIErrorCount);
    printf("%9u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));
}

 void
dag62se_print_extended_statistics_header(dag_card_ref_t card)
{
    dag_component_t any_component;
    dag_component_t root_component;
    attr_uuid_t any_attr;
    network_mode_t net_mode;
    ethernet_mode_t eth_mode;

    root_component = dag_config_get_root_component(card);
    
    /* Read Port information */
    any_component = dag_component_get_subcomponent(root_component, kComponentPort,0);
    /* check to see what type of stats to display */
    any_attr = dag_component_get_attribute_uuid(any_component, kUint32AttributeNetworkMode);
    net_mode = dag_config_get_uint32_attribute(card, any_attr);
    
    any_attr = dag_component_get_attribute_uuid(any_component, kUint32AttributeEthernetMode);
    eth_mode = dag_config_get_uint32_attribute(card, any_attr);

    switch(net_mode)
    {
        case kNetworkModePoS:
            /* PoS */
            printf("BIP1  BIP2  BIP3  C2  RxParity  ");
            break;
        case kNetworkModeEth:
            /* Eth */
            if ( eth_mode == kEthernetMode10GBase_LR)
            {
                /* LAN */
                printf("RxBytes  RxBytes_Bad  RxParity  ");  
            }
            else
            {
                /* WAN */
                printf("RxBytes  RxBytes_Bad  BIP1  BIP2  BIP3  C2  ");
            }
                
            break;
        default:
            break;
    }
}
 void 
dag62se_print_extended_statistics(dag_card_ref_t card_ref, int port)
{
    dag_component_t any_component;
    dag_component_t root_component;
    attr_uuid_t any_attr;
    network_mode_t net_mode;
    ethernet_mode_t eth_mode;

    root_component = dag_config_get_root_component(card_ref);
    
    /* Read Port information */
    any_component = dag_component_get_subcomponent(root_component, kComponentPort,port);
    /* check to see what type of stats to display */
    any_attr = dag_component_get_attribute_uuid(any_component, kUint32AttributeNetworkMode);
    net_mode = dag_config_get_uint32_attribute(card_ref, any_attr);
    
    any_attr = dag_component_get_attribute_uuid(any_component, kUint32AttributeEthernetMode);
    eth_mode = dag_config_get_uint32_attribute(card_ref, any_attr);

    /* Latch the counters */
    any_attr = dag_component_get_attribute_uuid(any_component, kBooleanAttributeCounterLatch);
    assert(any_attr != kNullAttributeUuid);
    dag_config_set_boolean_attribute(card_ref, any_attr, 1);
    

    switch(net_mode)
    {
        case kNetworkModePoS:
            /* PoS */
            /* BIP1 */
            any_attr = dag_component_get_attribute_uuid(any_component, kUint32AttributeB1ErrorCount);
            printf("%4u  ", dag_config_get_uint32_attribute(card_ref, any_attr));
            /* BIP2 */
            any_attr = dag_component_get_attribute_uuid(any_component, kUint32AttributeB2ErrorCount);
            printf("%4u  ", dag_config_get_uint32_attribute(card_ref, any_attr));
            /* BIP3 */
            any_attr = dag_component_get_attribute_uuid(any_component, kUint32AttributeB3ErrorCount);
            printf("%4u  ", dag_config_get_uint32_attribute(card_ref, any_attr));
            /* C2PathLabel */
            any_attr = dag_component_get_attribute_uuid(any_component, kUint32AttributeC2PathLabel);
            printf("%02x  ", dag_config_get_uint32_attribute(card_ref, any_attr));                  
            /* RxParity */
            any_attr = dag_component_get_attribute_uuid(any_component, kUint32AttributeRxParityError);
            printf("%8u  ", dag_config_get_uint32_attribute(card_ref, any_attr));              
                
            
            break;
        case kNetworkModeEth:
            /* Eth */
            if ( eth_mode == kEthernetMode10GBase_LR)
            {
                /* LAN */
                /* RxBytes */
                any_attr = dag_component_get_attribute_uuid(any_component, kUint64AttributeRxBytes);
                printf("%7"PRIu64"  ", dag_config_get_uint64_attribute(card_ref, any_attr));
                /* RxBytes_Bad */
                any_attr = dag_component_get_attribute_uuid(any_component, kUint64AttributeRxBytesBad);
                printf("%11"PRIu64"  ", dag_config_get_uint64_attribute(card_ref, any_attr));                
                /* RxParity */
                any_attr = dag_component_get_attribute_uuid(any_component, kUint32AttributeRxParityError);
                printf("%8u  ", dag_config_get_uint32_attribute(card_ref, any_attr));                 
                    
            }
            else
            {
                /* WAN */
                /* RxBytes */
                any_attr = dag_component_get_attribute_uuid(any_component, kUint64AttributeRxBytes);
                printf("%7"PRIu64"  ", dag_config_get_uint64_attribute(card_ref, any_attr));
                /* RxBytes_Bad */
                any_attr = dag_component_get_attribute_uuid(any_component, kUint64AttributeRxBytesBad);
                printf("%11"PRIu64"  ", dag_config_get_uint64_attribute(card_ref, any_attr));
                /* BIP1 */
                any_attr = dag_component_get_attribute_uuid(any_component, kUint32AttributeB1ErrorCount);
                printf("%4u  ", dag_config_get_uint32_attribute(card_ref, any_attr));
                /* BIP2 */
                any_attr = dag_component_get_attribute_uuid(any_component, kUint32AttributeB2ErrorCount);
                printf("%4u  ", dag_config_get_uint32_attribute(card_ref, any_attr));
                /* BIP3 */
                any_attr = dag_component_get_attribute_uuid(any_component, kUint32AttributeB3ErrorCount);
                printf("%4u  ", dag_config_get_uint32_attribute(card_ref, any_attr));
                /* C2PathLabel */
                any_attr = dag_component_get_attribute_uuid(any_component, kUint32AttributeC2PathLabel);
                printf("%02x  ", dag_config_get_uint32_attribute(card_ref, any_attr));
                /* RxParity */
                any_attr = dag_component_get_attribute_uuid(any_component, kUint32AttributeRxParityError);
                printf("%8u  ", dag_config_get_uint32_attribute(card_ref, any_attr));
            }
                
            break;
        default:
            break;
    }    
}
 
void
dag82x_print_tx_statistics_header()
{
    printf("TxFrames  TxBytes  ");
}

void
dag82x_print_tx_statistics(dag_card_ref_t card, int port)
{
     dag_component_t xgmii;
     dag_component_t xgmii_stats;
     dag_component_t root;
     attr_uuid_t attr = 0;
 
    root = dag_config_get_root_component(card);
    xgmii = dag_component_get_subcomponent(root, kComponentXGMII, 0);
    xgmii_stats = dag_component_get_subcomponent(xgmii, kComponentXGMIIStatistics, 0);
    attr = dag_component_get_attribute_uuid(xgmii_stats, kUint32AttributeTxFrames);
    print_attribute_value(card, attr);
    
    attr = dag_component_get_attribute_uuid(xgmii_stats, kUint64AttributeTxBytes);
    print_attribute_value(card, attr);
}

void
dag45ge_print_extended_statistics_header(ext_stat_t ext_stat_type)
{
     if( ext_stat_type & EXTENDED_CURRENT )
	  dag45ge_print_current_extended_statistics_header();
     if( ext_stat_type & EXTENDED_HI )
	  dag45ge_print_hi_extended_statistics_header();
     if( ext_stat_type & EXTENDED_LO )
	  dag45ge_print_lo_extended_statistics_header();
}
void
dag45ge_print_tx_statistics_header()
{
    printf("TxFrames  TxBytes  ");
}
void
dag45ge_print_current_extended_statistics_header()
{
    printf("TxFault  MiniMacLostSync  RemoteError  LOF  LOS  PeerLink  Link  RxFrames  RxBytes  CRCErrs  BadSmbls  ");
}

void
dag45ge_print_hi_extended_statistics_header()
{
    printf("Hi_TxFault  Hi_CRCError  Hi_RemoteError  Hi_LOF  Hi_LOS  Hi_PeerLink  Hi_Link  ");
}
 void
dag45ge_print_lo_extended_statistics_header()
{
    printf("Lo_TxFault  Lo_CRCError  Lo_RemoteError  Lo_LOF  Lo_LOS  Lo_PeerLink  Lo_Link  ");
}

 void
dag45ge_print_extended_statistics(dag_card_ref_t card_ref, int port, ext_stat_t ext_stat_type)
{
    dag_component_t minimacstat_component;
    dag_component_t port_component;
    dag_component_t root_component;

    root_component = dag_config_get_root_component(card_ref);
    /* Read Port Information */
    port_component = dag_component_get_subcomponent(root_component, kComponentPort, port);
    assert(port_component);
    minimacstat_component = dag_component_get_subcomponent(port_component, kComponentMiniMacStatistics, 0);
    if(minimacstat_component == NULL)
    {
        /* no component exists */
        return;
    }
    if( ext_stat_type & EXTENDED_CURRENT )
        dag45ge_print_current_extended_statistics_for_component(card_ref, minimacstat_component);
    if( ext_stat_type & EXTENDED_HI )
        dag45ge_print_hi_extended_statistics_for_component(card_ref, minimacstat_component);
    if( ext_stat_type & EXTENDED_LO )
        dag45ge_print_lo_extended_statistics_for_component(card_ref, minimacstat_component);
    if( ext_stat_type & EXTENDED_LO || ext_stat_type & EXTENDED_HI )
    {
		 /* FIXME: need to CLEAR the hi/lo here! */
    }
}

void
dag45ge_print_current_extended_statistics_for_component(dag_card_ref_t card_ref, dag_component_t minimacstat_component)
{
    attr_uuid_t any_attribute;
    
    /* TXFault */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributeSFPTxFaultCurrent);
    assert(any_attribute != kNullAttributeUuid);
    printf("%7u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));
    
    /* MiniMacLostSync */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributeMiniMacLostSync);
    assert(any_attribute != kNullAttributeUuid);
    printf("%15u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));

    /*RemoteError */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributeRemoteErrorCurrent);
    assert(any_attribute != kNullAttributeUuid);
    printf("%11u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));

    /* LOF */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributeLossOfFramingCurrent);
    assert(any_attribute != kNullAttributeUuid);
    printf("%3u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));

    /* LOS */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributeSFPLossOfSignalCurrent);
    assert(any_attribute != kNullAttributeUuid);
    printf("%3u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));

    /* PeerLink */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributePeerLinkCurrent);
    assert(any_attribute != kNullAttributeUuid);
    printf("%8u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));
    
    /* Link */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributeLinkCurrent);
    assert(any_attribute != kNullAttributeUuid);
    printf("%4u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));

    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kUint32AttributeRxFrames);
    assert(any_attribute != kNullAttributeUuid);
    printf("%8u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));

    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kUint64AttributeRxBytes);
    assert(any_attribute != kNullAttributeUuid);
    printf("%7"PRIu64"  ", dag_config_get_uint64_attribute(card_ref, any_attribute));

    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kUint32AttributeCRCErrors);
    assert(any_attribute != kNullAttributeUuid);
    printf("%7u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));

    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kUint32AttributeBadSymbols);
    assert(any_attribute != kNullAttributeUuid);
    printf("%8u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));
}

void
dag45ge_print_tx_statistics(dag_card_ref_t card_ref, int port)
{
    dag_component_t minimacstat_component;
    dag_component_t port_component;
    dag_component_t root_component;
    attr_uuid_t any_attribute;

    root_component = dag_config_get_root_component(card_ref);
    /* Read Port Information */
    port_component = dag_component_get_subcomponent(root_component, kComponentPort, port);
    minimacstat_component = dag_component_get_subcomponent(port_component, kComponentMiniMacStatistics, 0);
    if(minimacstat_component == NULL)
    {
        /* no component exists */
        return;
    }
     /* Read Port Information */
    port_component = dag_component_get_subcomponent(root_component, kComponentPort, port);
    assert(port_component);
    minimacstat_component = dag_component_get_subcomponent(port_component, kComponentMiniMacStatistics, 0);

    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kUint32AttributeTxFrames);
    assert(any_attribute != kNullAttributeUuid);
    printf("%8u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));
    
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kUint64AttributeTxBytes);
    assert(any_attribute != kNullAttributeUuid);
    printf("%7" PRIu64"  ", dag_config_get_uint64_attribute(card_ref, any_attribute));
}

void
dag45ge_print_hi_extended_statistics_for_component(dag_card_ref_t card_ref, dag_component_t minimacstat_component)
{
    attr_uuid_t any_attribute;

    /* TXFault */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributeSFPTxFaultEverHi);
    assert(any_attribute != kNullAttributeUuid);
    printf("%10u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));

    /* CRCError */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributeCRCErrorEverHi);
    assert(any_attribute != kNullAttributeUuid);
    printf("%11u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));

    /*RemoteError */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributeRemoteErrorEverHi);
    assert(any_attribute != kNullAttributeUuid);
    printf("%14u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));

    /* LOF */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributeLossOfFramingEverHi);
    assert(any_attribute != kNullAttributeUuid);
    printf("%6u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));

    /* LOS */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributeSFPLossOfSignalEverHi);
    assert(any_attribute != kNullAttributeUuid);
    printf("%6u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));

    /* PeerLink */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributePeerLinkEverHi);
    assert(any_attribute != kNullAttributeUuid);
    printf("%11u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));

    /* Link */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributeLinkEverHi);
    assert(any_attribute != kNullAttributeUuid);
    printf("%7u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));
}

void
dag45ge_print_lo_extended_statistics_for_component(dag_card_ref_t card_ref, dag_component_t minimacstat_component)
{
    attr_uuid_t any_attribute;

    /* TXFault */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributeSFPTxFaultEverLo);
    assert(any_attribute != kNullAttributeUuid);
    printf("%10u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));

    /* CRCError */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributeCRCErrorEverLo);
    assert(any_attribute != kNullAttributeUuid);
    printf("%11u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));

    /*RemoteError */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributeRemoteErrorEverLo);
    assert(any_attribute != kNullAttributeUuid);
    printf("%14u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));

    /* LOF */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributeLossOfFramingEverLo);
    assert(any_attribute != kNullAttributeUuid);
    printf("%6u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));

    /* LOS */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributeSFPLossOfSignalEverLo);
    assert(any_attribute != kNullAttributeUuid);
    printf("%6u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));

    /* PeerLink */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributePeerLinkEverLo);
    assert(any_attribute != kNullAttributeUuid);
    printf("%11u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));

    /* Link */
    any_attribute = dag_component_get_attribute_uuid(minimacstat_component, kBooleanAttributeLinkEverLo);
    assert(any_attribute != kNullAttributeUuid);
    printf("%7u  ", dag_config_get_boolean_attribute(card_ref, any_attribute));
}

//not used any more
// void
// dag50s_print_tx_statistics_header()
// {
//     printf("TxFrames    TxBytes  ");
// }
// 
// void
// dag50s_print_tx_statistics(dag_card_ref_t card_ref, int port)
// {
//     dag_component_t any_component;
//     dag_component_t root_component;
//     attr_uuid_t any_attribute;
// 
//     root_component = dag_config_get_root_component(card_ref);
//     any_component = dag_component_get_subcomponent(root_component, kComponentDeframer, port);
// 
//     /* TXFrames */
//     any_attribute = dag_component_get_attribute_uuid(any_component, kUint32AttributeTxFrames);
//     printf("%8u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));
//     /* TXBytes */
//     any_attribute = dag_component_get_attribute_uuid(any_component, kUint32AttributeTxBytes);
//     printf("%9u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));
// }


void
dag52sxa_print_extended_statistics_header()
{
    printf("B1_Count  B2_Count  B3_Count  REI_Count  J0  J1  C2  ");
}

void
dag52sxa_print_extended_statistics(dag_card_ref_t card_ref, int port)
{
    dag_component_t any_component;
    dag_component_t root_component;
    attr_uuid_t any_attribute;

    root_component = dag_config_get_root_component(card_ref);
    any_component = dag_component_get_subcomponent(root_component, kComponentDeframer, port);
 
    /* Latch and clear is done in the calling function */
    
    /* B1_Count */
    any_attribute = dag_component_get_attribute_uuid(any_component, kUint32AttributeB1ErrorCount);
    printf("%8u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));
    /* B2_Count */
    any_attribute = dag_component_get_attribute_uuid(any_component, kUint32AttributeB2ErrorCount);
    printf("%8u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));
    /* B3_Count */
    any_attribute = dag_component_get_attribute_uuid(any_component, kUint32AttributeB3ErrorCount);
    printf("%8u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));
    /* REI_count */
    any_attribute = dag_component_get_attribute_uuid(any_component, kUint32AttributeREIErrorCount);
    printf("%9u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));
    /* J0 */
    any_attribute = dag_component_get_attribute_uuid(any_component, kUint32AttributeJ0PathLabel);
    printf("%3u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));
    /* J1 */
    any_attribute = dag_component_get_attribute_uuid(any_component, kUint32AttributeJ1PathLabel);
    printf("%2u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));
    /* C2 */
    any_attribute = dag_component_get_attribute_uuid(any_component, kUint32AttributeC2PathLabel);
    printf("%2u  ", dag_config_get_uint32_attribute(card_ref, any_attribute));
}

void
dagx_print_extended_statistics_header(dag_card_ref_t card_ref)
{
	attr_uuid_t any_attribute;
	dag_component_t root;
	dag_component_t comp;
	dag_attribute_code_t code;
	int comp_count = 0;
	int attr_count = 0;
	int i = 0;
	int j = 0;
    dag_component_code_t comp_code;
    int h = 0;

	root = dag_config_get_root_component(card_ref);
    for(h = 0; h < sizeof(ext_comp_codes)/sizeof(ext_comp_codes[0]); h++) {
        /* try each component type */
        comp_code = ext_comp_codes[h];
        comp_count = dag_config_get_recursive_component_count(card_ref, comp_code);//dag_component_get_subcomponent_count_of_type(root, comp_code);
        for (i = 0; ((i < comp_count) && (i < 1)); i++)
        {
            comp = dag_config_get_recursive_indexed_component(card_ref, comp_code,i);//dag_component_get_subcomponent(root, comp_code, i);
//	    printf("comp-%d %d ->%s\n", h, i, dag_config_get_component_name(comp));
            attr_count = dag_component_get_attribute_count(comp);
            for (j = 0; j < attr_count; j++)
            {
                any_attribute = dag_component_get_indexed_attribute_uuid(comp, j);
                code = dag_config_get_attribute_code(any_attribute);
                if (attribute_is_printable(card_ref, any_attribute))
                {
                    attribute_print_header(card_ref, any_attribute);
                }
            }
        }
        if (comp_count > 0) {
        }
    }
}

void
dagx_print_extended_statistics(dag_card_ref_t card_ref, int port) {
	attr_uuid_t any_attribute;
	dag_component_t root;
	dag_component_t comp;
	dag_attribute_code_t code;
	int comp_count = 0;
	int attr_count = 0;
	int i = 0;
	int j = 0;
    dag_component_code_t comp_code;
    int h = 0;

	root = dag_config_get_root_component(card_ref);
    for(h = 0; h < sizeof(ext_comp_codes)/sizeof(ext_comp_codes[0]); h++) {
        /* try each component type */
        comp_code = ext_comp_codes[h];
        comp_count = dag_config_get_recursive_component_count(card_ref, comp_code);//dag_component_get_subcomponent_count_of_type(root, comp_code);
	if( comp_count > 1 )
	{
	    comp_count = port+1;
	    i = port;
	} else
	  i = 0;
	
        for (; i < comp_count; i++)
        {
            dag_config_state_t comp_state;
            comp = dag_config_get_recursive_indexed_component(card_ref, comp_code,i);
            if(NULL == comp )break;
            comp_state = dag_config_get_component_state(comp);
            attr_count = dag_component_get_attribute_count(comp);
            for (j = 0; j < attr_count; j++)
            {
                any_attribute = dag_component_get_indexed_attribute_uuid(comp, j);
                code = dag_config_get_attribute_code(any_attribute);
                if (attribute_is_printable(card_ref, any_attribute))
                {
                    attribute_print_value(card_ref, any_attribute, comp_state,i);
                }
            }
        }
        if (comp_count > 0) {
        }
    }
}


/*
 * Print only the non-boolean status attributes (Boolean status are printed in statistics.
 */
static bool
attribute_is_printable(dag_card_ref_t card_ref, attr_uuid_t attr)
{
	dag_attr_config_status_t cs;
	dag_attr_t type;
	dag_attribute_code_t code;
    int verbosity = dagutil_get_verbosity();
    int i = 0;
	cs = dag_config_get_attribute_config_status(attr);
	if (cs != kDagAttrStatus){
		return false;
	};

    /* list of exceptions */
	code = dag_config_get_attribute_code(attr);
   switch (code)
	{
    case kAttributeInvalid:
        /* dummy placeholder for exceptions */
        return false;

    default: 
	    
        /* do nothing */
	   break;
	};

    /* if the attribute is boolean return false */
    type = dag_config_get_attribute_valuetype(card_ref, attr);
    if ( kAttributeBoolean == type ) 
        return false;
    /* verbosity 3 and above print all boolean attribs */
	if(verbosity >=  3)
		 return true;
     /* Check the attribute is to be printed at this verbosity level*/
    for( i = 0; i < ( sizeof (ext_attr_verbose_array) / sizeof(ext_attr_verbose_array[0])) ; i++)
    {
        if (code == ext_attr_verbose_array[i].attribute_code)
        {
            if (ext_attr_verbose_array[i].attribute_verbosity > verbosity)
                return false;
            else
                return true;
        }
    }
    return false;
#if 0
    type = dag_config_get_attribute_valuetype(card_ref, attr);
    switch (type) {
    case kAttributeChar:
    case kAttributeInt32:
    case kAttributeUint32:
    case kAttributeInt64:
    case kAttributeUint64:
        return true;
    default:
        return false;
    }
#endif 
}

