// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @file BenchMark_main.cpp
 *
 */

#include "BenchmarkPublisher.h"
#include "BenchmarkSubscriber.h"

#include <fastrtps/Domain.h>
#include <fastrtps/log/Log.h>

using namespace eprosima;
using namespace fastrtps;
using namespace rtps;

int main(int argc, char** argv)
{
    int type = 1;
    int transport = 1;
    bool paramsOk = true;
	std::string topic = "BenchMarkTopicTCP";
	int domain = 0;
	int size = 0;
	int test_time = 10000;
	int tick_time = 100;
	int wait_time = 1000;
	ReliabilityQosPolicyKind kind = RELIABLE_RELIABILITY_QOS;

    if(argc >= 2)
    {
        if(strcmp(argv[1],"publisher")==0)
        {
            type = 1;
        }
        else if(strcmp(argv[1],"subscriber")==0)
        {
            type = 2;
        }
        else
        {
            paramsOk = false;
        }

        if (paramsOk && argc > 2)
        {
            if (strcmp(argv[2], "udp") == 0)
            {
                transport = 1;
            }
            else if (strcmp(argv[2], "tcp") == 0)
            {
                transport = 2;
            }
            else if (strcmp(argv[2], "udp6") == 0)
            {
                transport = 3;
            }
            else if (strcmp(argv[2], "tcp6") == 0)
            {
                transport = 4;
            }
            else
            {
                paramsOk = false;
            }
        }
		if (argc > 3)
		{
			if (argc % 2 == 0)
			{
				paramsOk = false;
			}
			for (int i = 3; i < argc; i += 2)
			{
				if (strcmp(argv[i], "-topic") == 0)
				{
					topic = argv[i + 1];
				}
				else if (strcmp(argv[i], "-domain") == 0)
				{
					domain = atoi(argv[i + 1]);
				}
				else if (strcmp(argv[i], "-time") == 0)
				{
					test_time = atoi(argv[i + 1]);
				}
				else if (strcmp(argv[i], "-size") == 0)
				{
					if (strcmp(argv[i + 1], "none") == 0)
					{
						size = 0;
					}
					else if (strcmp(argv[i + 1], "small") == 0)
					{
						size = 1;
					}
					else if (strcmp(argv[i + 1], "medium") == 0)
					{
						size = 2;
					}
					else if (strcmp(argv[i + 1], "big") == 0)
					{
						size = 3;
					}
					else
					{
						paramsOk = false;
					}
				}
				else if (strcmp(argv[i], "-reliable") == 0)
				{
					if (strcmp(argv[i + 1], "true") == 0)
					{
						kind = RELIABLE_RELIABILITY_QOS;
					}
					else if (strcmp(argv[i + 1], "false") == 0)
					{
						kind = BEST_EFFORT_RELIABILITY_QOS;
					}
					else
					{
						paramsOk = false;
					}
				}
				else if (strcmp(argv[i], "-tick") == 0)
				{
					tick_time = atoi(argv[i + 1]);
				}
				else if (strcmp(argv[i], "-wait") == 0)
				{
					wait_time = atoi(argv[i + 1]);
				}
				else
				{
					paramsOk = false;
				}
			}
		}
    }
	else
	{
		paramsOk = false;
	}

    if (!paramsOk)
    {
		std::cout << "publisher OR subscriber argument needed" << std::endl;
		std::cout << "tcp OR udp argument needed" << std::endl;
		std::cout << "-------------------------------------------------------------------- " << std::endl;
		std::cout << "Common optional arguments: [-topic] [-domain][-reliable] " << std::endl;
		std::cout << "\t-topic: Prefix topic for the communication " << std::endl;
		std::cout << "\t-domain: Domain id " << std::endl;
		std::cout << "\t-reliable: Sets if the communication is going to be Reliable or Best_Effort. Values [true] [false] " << std::endl;
		std::cout << "\t-size: Size of the message. Values [none] [small] [medium] [big] " << std::endl;
		std::cout << "\t\t: none. The message only contains an int value" << std::endl;
		std::cout << "\t\t: small. The message contains an int value and an array of 16Kb " << std::endl;
		std::cout << "\t\t: medium. The message contains an int value and an array of 512Kb" << std::endl;
		std::cout << "\t\t: big. The message contains an int value and an array of 8Mb" << std::endl;
		std::cout << "-------------------------------------------------------------------- " << std::endl;
		std::cout << "publisher has an optional argument: [time] " << std::endl;
		std::cout << "\t-wait: Milliseconds before starting the sampling. " << std::endl;
		std::cout << "\t-time: Milliseconds that the test is going to run. " << std::endl;
		std::cout << "\t-tick: Milliseconds to take samples of the performance. " << std::endl;
		std::cout << "-------------------------------------------------------------------- " << std::endl;
        Log::Reset();
        return 0;
    }

    switch(type)
    {
        case 1:
            {
				BenchMarkPublisher* mypub = new BenchMarkPublisher();
                if(mypub->init(transport, kind, test_time, tick_time, wait_time, topic, domain, size))
                {
                    mypub->run();
                }
				delete mypub;
                break;
            }
        case 2:
            {
                BenchMarkSubscriber* mysub = new BenchMarkSubscriber();
                if(mysub->init(transport, kind, topic, domain, size))
                {
                    mysub->run();
                }
				delete mysub;
                break;
            }
    }
    Domain::stopAll();
    Log::Reset();
    return 0;
}
