/*****************************************************************************/
/* Copyright (c) 2009 NXP B.V.                                               */
/*                                                                           */
/* This library is free software; you can redistribute it and/or             */
/* modify it under the terms of the GNU Lesser General Public                */
/* License as published by the Free Software Foundation, using               */
/* version 2.1 of the License.                                               */
/*                                                                           */
/* This library is distributed in the hope that it will be useful,           */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of            */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU          */
/* Lesser General Public License for more details.                           */
/*                                                                           */
/* You should have received a copy of the GNU Lesser General Public          */
/* License along with this library; if not, write to the Free Software       */
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA   */
/*                                                                           */
/*****************************************************************************/
/**
    @file   phStbDbg_UnitTestLinux.c
    @brief  Unit test for phStbDbg on Linux.

@b  Component:  phStbDbg.

*//*

Rev Date        Author      Comments
--------------------------------------------------------------------------------
  1 20050628    batelaan    Original
  2 20050628    batelaan    Crosscheck fixes.
  3 20050712    batelaan    Add more tests.
  4 20061109    G.Lawrance  Fix after tmDbg.h changes
  5 20061206    F.Raiyat    Added test for: DBG_CHK, DBG_ERR_CHK, DBG_ERR_DEPART
  6 20061207    F.Raiyat    minor fix task issues
  7 20090120    batelaan    Update file copyright/license text
--------------------------------------------------------------------------------
    For consistency and standardisation retain the Section Separators.
*/

/***********************************************
* INCLUDE FILES                                *
************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <phStbDbg.h>

/***********************************************
* LOCAL MACROS                                 *
* recommendation only: <MODULE><_WORD>+        *
************************************************/

/******************************************************************
* LOCAL TYPEDEFS                                                  *
* recommendation only:                     [p]phStbDbg_<Word>+_t  *
*******************************************************************/

/******************************************************************
* STATIC FUNCTION PROTOTYPES                  <Module>_<Word>+    *
*******************************************************************/

/******************************************************************
* STATIC DATA                  g[k|p|kp|pk|kpk]<Module>_<Word>+   *
*******************************************************************/

DBG_UNIT_STATIC(gDbgUnit);

/******************************************************************
* EXPORTED DATA                  g[k|p|kp|pk|kpk]phStbDbg_<Word>+ *
*******************************************************************/

/*******************************************************************************
* FUNCTION IMPLEMENTATION  <Module>[_<Word>+] for static functions             *
*                          tm[<layer>]<Module>[_<Word>+] for exported functions*
********************************************************************************/
static void test(long level);
static void test2(void);
static void usage(void);

/******************************************************************************/
static void test(long level)
{
    fprintf(stderr, "You should see %ld messages on syslog; try: tail /var/log/messages\n", level);

    DBG_PRINT1(gDbgUnit, DBG_LEVEL_1, "Level 1 message (flags = 0x%x)", DBG_LEVEL_1);
    DBG_PRINT1(gDbgUnit, DBG_LEVEL_2, "Level 2 message (flags = 0x%x)", DBG_LEVEL_2);
    DBG_PRINT1(gDbgUnit, DBG_LEVEL_3, "Level 3 message (flags = 0x%x)", DBG_LEVEL_3);
    DBG_PRINT1(gDbgUnit, DBG_LEVEL_4, "Level 4 message (flags = 0x%x)", DBG_LEVEL_4);
    DBG_PRINT1(gDbgUnit, DBG_LEVEL_5, "Level 5 message (flags = 0x%x)", DBG_LEVEL_5);
}

/******************************************************************************/
static void test2(void)
{
    DBG_SET_FLAGS(gDbgUnit, DBG_INTERFACE_ENTER);
    DBG_PRINT0(gDbgUnit, DBG_INTERFACE_ENTER, "DBG_INTERFACE_ENTER");

    DBG_SET_FLAGS(gDbgUnit, DBG_INTERFACE_LEAVE);
    DBG_PRINT0(gDbgUnit, DBG_INTERFACE_LEAVE, "DBG_INTERFACE_LEAVE");

    DBG_SET_FLAGS(gDbgUnit, DBG_INTERNAL_ENTER);
    DBG_PRINT0(gDbgUnit, DBG_INTERNAL_ENTER, "DBG_INTERNAL_ENTER");

    DBG_SET_FLAGS(gDbgUnit, DBG_INTERNAL_LEAVE);
    DBG_PRINT0(gDbgUnit, DBG_INTERNAL_LEAVE, "DBG_INTERNAL_LEAVE");

    DBG_SET_FLAGS(gDbgUnit, DBG_EXTERNAL_CALL);
    DBG_PRINT0(gDbgUnit, DBG_EXTERNAL_CALL, "DBG_EXTERNAL_CALL");

    DBG_SET_FLAGS(gDbgUnit, DBG_EXTERNAL_RETURN);
    DBG_PRINT0(gDbgUnit, DBG_EXTERNAL_RETURN, "DBG_EXTERNAL_RETURN");

    DBG_SET_FLAGS(gDbgUnit, DBG_WARNING);
    DBG_PRINT0(gDbgUnit, DBG_WARNING, "DBG_WARNING");

    DBG_SET_FLAGS(gDbgUnit, DBG_STATE);
    DBG_PRINT0(gDbgUnit, DBG_STATE, "DBG_STATE");

    DBG_SET_FLAGS(gDbgUnit, DBG_EVENTIN);
    DBG_PRINT0(gDbgUnit, DBG_EVENTIN, "DBG_EVENTIN");

    DBG_SET_FLAGS(gDbgUnit, DBG_EVENTOUT);
    DBG_PRINT0(gDbgUnit, DBG_EVENTOUT, "DBG_EVENTOUT");
}

/******************************************************************************/
static void usage(void)
{
    puts("Usage: phStbDbg_UnitTest [-assert2] <1|2|3|4|5>");
    puts("Tests phStbDbg DBG_PRINT macros.");
    puts("The higher the number the more output is printed.");
}

/******************************************************************************/
int main(int argc, char **argv)
{
    long level;
    int i;
    tmErrorCode_t err = 0;
    Bool useAssert2 = 0;
    UInt32 levels[] = {
        DBG_LEVEL_1_AND_BELOW,
        DBG_LEVEL_2_AND_BELOW,
        DBG_LEVEL_3_AND_BELOW,
        DBG_LEVEL_4_AND_BELOW,
        DBG_LEVEL_5_AND_BELOW     
    };
    if (argc < 2)
    {
        usage();
        return 1;
    }

    for (i = 1; i < argc; i++)
    {
        Char *arg = argv[i];
        if (strcmp(arg, "-assert2") == 0)
        {
            useAssert2 = 1;
            continue;
        }
        if (arg[0] == '-')
        {
            fprintf(stderr, "Unknown option (%s)\n", arg);
            usage();
            return 1;
        }
        // not an option
        break;
    }
    if (i < argc - 1)
    {
        fprintf(stderr, "Insufficient arguments\n");
        usage();
        return 1;
    }
    if (i > argc - 1)
    {
        fprintf(stderr, "Too many arguments\n");
        usage();
        return 1;
    }
    level = atol(argv[i]);
    fprintf(stderr, "You've chosen level %lu as specified by first argument \"%s\"\n",
            level, argv[i]);

    if (level < 1 || level > 5)
    {
        fprintf(stderr, "Level (%s) should be 1-5\n", argv[i]);
        return 1;
    }

    {
        /* I'm testing DBG_UNIT_EXTERN here, that's why it's located here: */
        DBG_UNIT_EXTERN(gDbgUnit);
        DBG_SET_FLAGS(gDbgUnit, levels[level - 1]);
    }

    {   /* I'm testing new DBG features from Southampton */        
        printf("Testing  DBG_CHK\n");
        DBG_CHK(5, (1+2),  "aaa");// Bad
        DBG_CHK(1, (2-1),  "bbb");// good
        DBG_CHK(0, (1+2),  "ccc");// Bad
       
        printf("Testing  DBG_TM_ERR_CHK\n");
        DBG_ERR_CHK(5, (1+2),  "aaa");// Bad
        DBG_ERR_CHK(1, (2-1),  "bbb");// good
        DBG_ERR_CHK(0, (1+2),  "ccc");// Bad

        printf("Testing  DBG_DEPART_ON_ERR\n");
        DBG_ERR_DEPART(5, (1+2),  "aaa");// Bad
        printf("zzzzzzzzzzzz Should NOT see this !!!\n");
    }
DEPARTURES:

    fprintf(stderr,
            "\nYou will only see DBG_PRINT output if this program is compiled\n"
            "for debug or trace mode!\n");

    test(level);
    test2();

    DBG_PRINT((gDbgUnit, DBG_WARNING, "Generating an assert..."));
    if (useAssert2)
    {
        fprintf(stderr, "Finishing with invoking DBG_ASSERT2...\n");
        DBG_ASSERT2(1 == 2, ("a DBG_ASSERT2 test assertion"));
    }
    else
    {
        fprintf(stderr, "Finishing with invoking DBG_ASSERT...\n");
        DBG_ASSERT(1 == 2);
    }
    

    
    return 0;
}

/******************************************************************************/
