function rtiostreamtest(connection, varargin)
%RTIOSTREAMTEST   Test suite for rtiostream
%   RTIOSTREAMTEST('tcp', hostname, port) Connect to the target via TCP/IP 
%   using the specified hostname and port.
%
%   RTIOSTREAMTEST('serial', port, baudrate) Connect to the target via 
%   serial using the specified port and baudrate.
%
%   For example: 
%
%   rtiostreamtest('tcp', 'localhost', 2345)
%   rtiostreamtest('serial', 'COM1', 9600)

%   Copyright 2012 The MathWorks, Inc.

narginchk(1, inf);

% Get or create properties
verbose = false;
paramsClass = 'coder.rtiostreamtest.Parameters';

if ischar(connection)
    narginchk(3, inf);
    properties = coder.rtiostreamtest.Parameters. ...
        getParameterInstance(connection, varargin);    
    assert(isa(properties, paramsClass), ...
        'Expected %s', paramsClass);
elseif isa(connection, paramsClass)        
    properties = connection;
else
    coder.rtiostreamtest.Test.error('InvalidConnection');
end

% Get verbose
if ~isempty(varargin) && strcmp(varargin(end), 'verbose')
    verbose = true;
end

% Initialize and detect target
coder.rtiostreamtest.Test.majorheader('TestSuiteTitle');
coder.rtiostreamtest.Test.println('InitializingConnection');

server = initialize_connection(properties, verbose);

% Perform the tests
coder.rtiostreamtest.Test.header('TestResults');
runner = coder.rtiostreamtest.TestRunner(properties.getTests());
runner.runTest(server, {'verbose', verbose});

coder.rtiostreamtest.Test.majorheader('AllTestsPassed');
end

function connection = initialize_connection(properties, verbose)
%INITIALIZE_CONNECTION creates a connection with a target server
%
%   PROPERTIES -
%       coder.rtiostreamtest.Parameters instance with parameters required to
%       open the connection
%   VERBOSE    -
%       whether verbose output is enabled

import coder.rtiostreamtest.*;

[library, parameters] = properties.getSharedLibrary();

id = tic;
connection = coder.rtiostreamtest.ServerConnection(library, parameters, verbose);
inittime = toc(id);

Test.verboseln(verbose, 'ConnectionEstablishedVerbose', inittime);

Test.headerraw( Test.buildhyperlink( Test.message('HardwareDiscovered'), ...
    Test.message('HardwareDiscovered_hint')) );

if connection.littleEndian
    endianMsg = Test.message('LittleEndianDevice');
else
    endianMsg = Test.message('BigEndianDevice');
end

fprintf ([ ...
    Test.messageln('LabelCharacter', connection.charSize*8) ...
    Test.messageln('LabelShort', connection.shortSize*8) ...
    Test.messageln('LabelInteger', connection.intSize*8) ...
    Test.messageln('LabelLong', connection.longSize*8) ...
    Test.messageln('LabelFloat', connection.floatSize*8) ...
    Test.messageln('LabelDouble', connection.doubleSize*8) ...
    Test.messageln('LabelPointer', connection.pointerSize*8) ....
    Test.messageln('LabelEndianness', endianMsg)]);

Test.header('RtiostreamDiscovered');

if connection.isTargetBlockingOnReceive
   blockOnReceiveMsg = Test.message('DeviceBlocksOnReceive');
else
   blockOnReceiveMsg = Test.message('DeviceDoesntBlockOnReceive');
end

fprintf ([ ...
    Test.buildhyperlink( Test.message('Label_RoundTrip_short'), ...
        Test.message('Label_RoundTrip_hint') ) ' : ' Test.message( 'milliseconds', connection.RTT*1000 ) '\n' ...
    Test.buildhyperlink( Test.message('Label_Blocking_short'), ...
        Test.message('Label_Blocking_hint') ) ' : ' ...
           blockOnReceiveMsg '\n']);
end
