/**
 * Copyright (c) 2006 - 2009 Smaxe Ltd (www.smaxe.com).
 * All rights reserved.
 */

import com.smaxe.app.uv.agent.rtmp.RtmpClientInfo;
import com.smaxe.app.uv.loadtester.rtmp.RtmpTester;

import java.util.HashMap;
import java.util.Map;

/**
 * <code>RtmpTesterLauncher</code> - {@link RtmpTester} launcher.
 * 
 * @author Andrei Sochirca
 */
public final class RtmpTesterLauncher extends Object
{
    /**
     * Entry point.
     * 
     * @param args
     * @throws Exception
     */
    public static void main(final String[] args) throws Exception
    {
        // NOTE:
        // Evaluation version has a few limitations:
        // 1. only "localhost" connection is allowed (url like: rtmp://localhost:1935/live)
        // 2. only one client script executed at a time
        // 3. client session duration is limited to 1 minute
        // You can buy license at:
        // http://www.smaxe.com/order.jsf
        RtmpTester.setKey("00000-00000-00000-00000-00000");
        
        // define client properties
        Map<String, Object> clientProperties = new HashMap<String, Object>();
        
        clientProperties.put("streamToPlay", "stream.flv");
        
        // client info
        RtmpClientInfo client = new RtmpClientInfo(script.PlayStreamScript.class.getCanonicalName(), clientProperties);
        
        client.setGatherSessionInfo(true);
        
        RtmpTester tester = new RtmpTester();
        
        tester.emulateClient("rtmp://localhost:1935/live", client,
                new RtmpTester.ICallback()
        {
            /**
             * Notifies about connection to the server.
             */
            public void onConnect(final RtmpTester.IClientSessionInfoProvider provider)
            {
                System.out.println("RtmpTesterCallback#onConnect: " + provider.id());
            }
            
            /**
             * Notifies about disconnection from the server.
             * You can use {@link RtmpTester.IClientSessionInfoProvider <tt>provider</tt>}
             * to get session details.
             */
            public void onDisconnect(final RtmpTester.IClientSessionInfoProvider provider)
            {
                System.out.println("RtmpTesterCallback#onDisconnect: " + provider.id());
                
                // NOTE:
                // RtmpTester can provide you with Bandwidth as a function of time
                System.out.println("Bandwidth(t):");
                for (Map<String, Object> entry : provider.getEntities(RtmpTester.IClientSessionInfoProvider.DATA_TRANSFER, null /*selector*/))
                {
                    // bandwidth entry represents a map (field name -> value)
                    // for example,
                    // {stimestamp=1297, readBytes=87237, writtenBytes=3420, readPackets=221, writtenPackets=5}
                    // where stimestamp is session timestamp
                    
                    System.out.println(entry);
                }
                
                // NOTE:
                // RtmpTester can provide you with Method Invocations (methods invoked by both client and server)
                System.out.println("Method invocation(t):");
                for (Map<String, Object> entry : provider.getEntities(RtmpTester.IClientSessionInfoProvider.METHOD_INVOCATION, null /*selector*/))
                {
                    // method invocation entry represents a map (field name -> value)
                    // for example,
                    // {stimestamp=203, source=CLIENT, method=createStream, arguments=null, result=33685, executionTime=47}
                    // where
                    //     stimestamp is session timestamp,
                    //     source is method invocation source (CLIENT or SERVER),
                    //     method is method name,
                    //     executionTime is method execution time, etc.
                    
                    System.out.println(entry);
                }
                
                // NOTE:
                // RtmpTester can provide you with SharedObject events
                System.out.println("Shared Object(t):");
                for (Map<String, Object> entry : provider.getEntities(RtmpTester.IClientSessionInfoProvider.SHARED_OBJECT, null /*selector*/))
                {
                    // shared object entry represents a map (field name -> value)
                    // for example,
                    // {name=test, version=15, data={attribute=16}}
                    // where
                    //     name is shared object name,
                    //     version is shared object version,
                    //     data is current shared object state,
                    
                    System.out.println(entry);
                }
                
                // NOTE:
                // RtmpTester can provide you with Streams (streams played or published by client)
                System.out.println("Stream(t):");
                for (Map<String, Object> entry : provider.getEntities(RtmpTester.IClientSessionInfoProvider.STREAM, null /*selector*/))
                {
                    // stream entry represents a map (field name -> value)
                    
                    System.out.println(entry);
                }
                
                // NOTE:
                // RtmpTester can provide you with low level RTMP events (events sent by both client and server)
                System.out.println("RTMP event(t):");
                for (Map<String, Object> entry : provider.getEntities(RtmpTester.IClientSessionInfoProvider.EVENT, null /*selector*/))
                {
                    // RTMP event entry represents a map (field name -> value)
                    // for example,
                    // {stimestamp=63, source=CLIENT, type=MI, stream=0, size=221, data=ClassObject [RTMP.INVOKE,{id=1, action=connect, parameters={objectEncoding=0, app=live, flashVer=WIN 9,0,124,0, fpad=false, tcUrl=rtmp://localhost:1935/live, audioCodecs=4095, videoFunction=1, pageUrl=, swfUrl=, videoCodecs=255}, arguments=null}]}
                    // where
                    //     stimestamp is session timestamp,
                    //     source is event source (CLIENT or SERVER), etc.
                    
                    System.out.println(entry);
                }
            }
            
            /**
             * Notifies about occurred exception.
             */
            public void onException(final RtmpTester.IClientSessionInfoProvider provider, final Exception e)
            {
                System.out.println("RtmpTesterCallback#onException: " + provider.id() + ", " + e.getMessage());
            }
        });
        
        while (tester.getClients() > 0)
        {
            Thread.sleep(5 * 1000);
        }
        
        tester.release();
    }
    
    /**
     * Constructor.
     */
    private RtmpTesterLauncher()
    {
    }
}