/*
 * Copyright (c) 2001-2003 Shiman Associates Inc. All Rights Reserved.
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "mas/mas.h"
#include "mas/mas_core.h"

void
usage( void )
{
    fprintf(stderr, "usage: masprobe [-h|-?] [-d di1 'name' | port1] [-d di2 'name' | port2]\n");
    fprintf(stderr, "       Inserts a datalog device inline between two ports.\n\n");
    fprintf(stderr, "options:\n");
    fprintf(stderr, "   -d di 'name' use port named 'name' on device di1.\n");
    
    fprintf(stderr, "   portnum      use port with number portnum.\n");
    fprintf(stderr, "\n");
    exit(2);
}

int
main(int argc, char* argv[])
{
    int32 err;
    int i;
    int a = 0;
    int has_pnum[2];
    long t;
    int32 pnum[2];
    int32 di[2];
    char *pname[2];
    mas_port_t port[2];
    mas_device_t device[2];
    mas_device_t dlog;
    mas_port_t dlog_snk, dlog_src;

    /* we need at least two portnums */
    if ( argc < 3 )
        usage();
    
    for (i=1; i<argc && a<2; i++)
    {
        if ( argv[i][0] != '-' )
        {
            t = strtol(argv[i], (char **)NULL, 10);
            if ( t == LONG_MIN || t == LONG_MAX )
            {
                fprintf(stderr, "Invalid value for port %d", a+1 );
                usage();
            }
            
            has_pnum[a] = TRUE;
            pnum[a] = t;
            a++;
        }
        else
        {
            switch(argv[i][1])
            {
            case 'd':
                if ( i + 2 >= argc )
                {
                    fprintf(stderr, "Not enough options for -d\n\n");
                    usage();
                }
                
                has_pnum[a] = FALSE;
                t = strtol(argv[++i], (char **)NULL, 10);
                if ( t == LONG_MIN || t == LONG_MAX )
                {
                    fprintf(stderr, "Invalid value for device instance %d\n\n", a+1 );
                    usage();
                }
                
                di[a] = t;
                pname[a] = argv[++i];
                a++;
                break;
            case 'h':
            case '?':
            default:
                usage();
                break;
            }
        }
    }

    if ( a < 2 )
    {
        fprintf(stderr, "masprobe requires two ports\n\n");
        usage();
    }
    
    masc_log_verbosity( MAS_VERBLVL_INFO );

    /* initiate contact with MAS */
    err = mas_init();
    if (err < 0)
    {
	printf("\nconnection with server failed.\n");
	exit(1);
    }

    for (i=0; i<2; i++)
    {
        if ( has_pnum[i] )
        {
            mas_get_port( pnum[i], NULL, &port[i] );
        }
        else
        {
            mas_get_device( di[i], NULL, &device[i] );
            err = mas_asm_get_port_by_name( device[i], pname[i], &port[i] );
            if ( err < 0 )
            {
                masc_log_message( MAS_VERBLVL_ERROR, "Port %d is invalid", i+1 );
                exit(2);
            }
        }
    }

    err = mas_asm_instantiate_device( "datalog", 0, 0, &dlog );
    mas_assert( err >= 0, "Couldn't instantiate datalog");
    
    {
        struct mas_package p;

        masc_setup_package( &p, NULL, 0, 0 );
        masc_pushk_string( &p, "mode", "header" );
        masc_finalize_package( &p );
        mas_set( dlog, "mode", &p );
        masc_strike_package( &p );
    }
    
    err = mas_asm_get_port_by_name( dlog, "sink", &dlog_snk );
    mas_assert( err >= 0, "Couldn't retrieve datalog sink");
    
    err = mas_asm_get_port_by_name( dlog, "source", &dlog_src );
    mas_assert( err >= 0, "Couldn't retrieve datalog source");

    err = mas_asm_connect_inline( port[0], dlog_snk, NULL, dlog_src, port[1], NULL, FALSE );
    mas_assert( err >= 0, "Couldn't connect datalog device inline");

    masc_log_message( 0, "Datalog output is in server log.");
    masc_log_message( 0, "Press [ENTER] to remove the device and end the program.");
    masc_log_message( 0, "Do NOT press ctrl-c!");
    getchar();
    
    err = mas_asm_disconnect_inline( port[0], dlog_snk, dlog_src, port[1], NULL, FALSE );
    mas_assert( err >= 0, "Couldn't disconnect datalog device");
    sleep(2);
    
    exit(0);
}
