/*
 * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
 *
 * 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.
 */

#include <libsoundmanager/libsoundmanager.hpp>
#include <iostream>
#include <glib-2.0/glib.h>
#include <fcntl.h>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <thread>
#include <exception>
#include <vector>
#include <sstream>

using namespace std;

static vector<string> split(const string& str, char sep);
LibSoundmanager* sm;

static void usage()
{
    cout << "verb "<< "key:arg" << endl;
	cout << "example:" << endl; 
	cout << "connect sourceID 100 sinkID 100" << endl;
	cout << "------- -------- --- " << endl;
	cout << "  verb    key    value" << endl;
	cout << "verb list:" << endl;
	for(auto itr = api_list.begin(); itr != api_list.end(); ++itr)
	{
		cout << "  " << *itr << endl;
	}
	// Todo output api list
	exit(0);
}

static void call_test()
{
	string command;

	cout << "input verb and argments" << endl;

	/* read the buffer */
	for(;;){
		char line[1023];
		cin.getline(line, sizeof(line));
		command = line;
		if(command.empty()){
			continue;
		}
		
		vector<string> v_command = split(command, ' ');
		/*for(auto itr = v_command.begin(); itr != v_command.end(); ++itr)
		{
			cout << *itr <<endl;
		}*/
		size_t num = v_command.size();
		if(num % 2 == 0){
			cout << "If command contains args, please input <key,value> in argument part" << endl;
			continue;
		}
		/* create json object */
		struct json_object* j_obj = json_object_new_object();
		for(int i = 1;i < (v_command.size()) ;++i){
			struct json_object* val		= json_object_new_string(v_command[i+1].c_str());
			json_object_object_add(j_obj, v_command[i].c_str(), val);
			++i;
		}
		/* call verb via libsoundmanager */
		sm->call(v_command[0], j_obj);
		/* free vector */
		vector<string>().swap(v_command);
		string().swap(command);
	}
}

static void onRep(struct json_object* reply_contents)
{
    const char* str = json_object_to_json_string(reply_contents);
    cout << "[CB onRep]: " << str << endl;
    json_object_put(reply_contents);
}

static void onEv(const string& event, struct json_object* event_contents)
{
    const char* str = json_object_to_json_string(event_contents);
    cout << "[CB onEvent]: event" << event.c_str() << "  contents:" << str << endl;
    json_object_put(event_contents);
}

static vector<string> split(const string& str, char sep)
{
    vector<string> v;
    stringstream ss(str);
    string buffer;
    while( getline(ss, buffer, sep) ) {
		if(!buffer.empty())
        	v.push_back(buffer);
    }
    return v;
}

int main(int argc, char **argv)
{
	int ret;
	if(argc == 1)
	{
		printf("Please input port num in first argument, and token in second argument");
		usage();
		return 0;
	}
	if(argc == 2)
	{
		string av(argv[1]);
		if( (av == "-h") || (av == "--help"))
		{
			usage();
			return 0;
		}	
	}

	string port_string(argv[1]);
	string token(argv[2]);
	char* endptr;
	long port = strtol(port_string.c_str(),&endptr,10);

    /* error check of range */
    if( (port > 20000) || (port < 0) )
    {
		printf("input under 20000(temporary number)");
        return 0;
    }
    if(*endptr != '\0')
    {
		printf("not number");
        return 0;
    }
	
    cout << "Call test for libsoundmanager" << endl;
	cout << "Call example: registerSource appname radio" << endl;
	sm = new LibSoundmanager(port, token);	
	sm->register_callback(&onEv, &onRep);

	if (ret < 0) {
		printf("failed to create event loop");
		return -1;
	}
	sm->run_eventloop();
	call_test();

	return 0;
}