/*
 * Copyright (C) 2009 - 2010 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */


#include <iostream>

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

#include "../CUIMessageHandler.h"
#include "DaemonDM/MessageListener.h"

#include "Logger.h"

const char* const c_MessageListenerLog = "MessageListener";

using namespace std;

using namespace NS_DM_Client;

//------------------------------------------------------------------------------------------------------
const size_t c_max_len = 256 + 1;

bool isDefaultUserInput = false;
char userInput[c_max_len];
bool isDefaultUserChoiseSet = false;
char userChoiseSet[c_max_len];
bool isDefaultUserConfirm = false;
char userConfirm[2];

bool cancelDownload = false;

//------------------------------------------------------------------------------------------------------

void print_usage(FILE* stream, const char* prog_name)
{
    fprintf(stream, "Usage: %s options \n", prog_name);

    fprintf(stream,
        "   -h              --help                  Display this usage information\n"
        "   -a              --alive                 Check if listener alive\n"
        "   -s              --stop                  Stop listener\n"
        "   -f              --fork                  Use fork for detach listener from current console\n"
        "   -i text         --input text            Set default user input\n"
        "   -c y|n          --confirm y|n           Set default user confirm. y - if confirm, n (or other) if not confirm\n"
        "   -o choise set   --choise choise set     Set default user choise set separated by \'-\'\n"
        "   -d cancel       --download cancel       Imitation of download cancelling by user\n"
    );
}
//------------------------------------------------------------------------------------------------------
void ProcessCommandLine(int argc, char** argv)
{
    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "ENTER >> ProcessCommandLine");

    /*
	int next_option;

    if (argc > 1)
    {
        // we have parameters in command line
        do
        {
            next_option = getopt_long(argc, argv, c_clSmallOptions, LongOptions, 0);
            switch (next_option)
            {
                case 'h':
                {
                    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "parse command line option: -h");
                    print_usage(stdout, argv[0]);
                    exit (EXIT_SUCCESS);
                }
                case 'a':
                {
                    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "parse command line option: -a");
                    pid_t pid;
                    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "status: %s", IsStarted(pid) ? "UI API listener is alive" : "UI API listener is not alive");
                    fprintf(stdout, (IsStarted(pid) ? "UI API listener is alive\n" : "UI API listener is not alive\n"));
                    exit (EXIT_SUCCESS);
                }
                case 's':
                {
                    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "parse command line option: -s");
                    pid_t pid;
                    if (IsStarted(pid))
                    {
                        LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "send  kill signal for stopping UI API listener");
                        fprintf (stdout, "start UI API listener stopping\n");
                        kill(pid, SIGUSR1);
                        exit (EXIT_SUCCESS);
                    }
                    else
                    {
                        LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "UI API listener is not runnign. Can't stop listener");
                        fprintf(stdout, "UI API listener is not runnign. Can't stop listener\n");
                        exit (EXIT_SUCCESS);
                    }
                    break;
                }
                case 'f':
                {
                    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "parse command line option: -f. swap to non console mode");
                    useFork = true;
                    break;
                }
                case 'i':
                {
                    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "parse command line option: -i");
                    String user_input = optarg;
                    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "defailt user input: %s", user_input.c_str());
                    if (!user_input.empty())
                    {
                        isDefaultUserInput = false;
                        if (user_input.size() > c_max_len)
                        {
                            fprintf (stdout, "UIAPIClientTest: default user input is too long. Max length = %d", c_max_len);
                        }
                        else
                        {
                            memcpy(userInput, user_input.c_str(), user_input.size());
                            userInput[user_input.size()] = '\0';
                            isDefaultUserInput = true;
                        }
                    }
                    else
                    {
                        fprintf (stdout, "UIAPIClientTest: default user input is empty. Fill correct argument list. Use -h for help\n");
                    }
                    break;
                }
                case 'c':
                {
                    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "parse command line option: -c");
                    String user_confirm = optarg;
                    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "defailt user confirm: %s", user_confirm.c_str());
                    if (!user_confirm.empty())
                    {
                        isDefaultUserConfirm = false;
                        if (user_confirm.size() > c_max_len)
                        {
                            fprintf (stdout, "UIAPIClientTest: default user confirm is too long. Max length = %d", c_max_len);
                        }
                        else
                        {
                            userConfirm[0] = user_confirm[0];
                            userConfirm[1] = '\0';
                            isDefaultUserConfirm = true;
                        }
                    }
                    else
                    {
                        fprintf (stdout, "UIAPIClientTest: default user confirm is empty. Fill correct argument list. Use -h for help\n");
                    }
                    break;
                }
                case 'o':
                {
                    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "parse command line option: -o");
                    String user_choise = optarg;
                    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "default user choise: %s", user_choise.c_str());
                    if (!user_choise.empty())
                    {
                        isDefaultUserChoiseSet = false;
                        if (user_choise.size() > c_max_len)
                        {
                            fprintf (stdout, "UIAPIClientTest: default user choise is too long. Max length = %d", c_max_len);
                        }
                        else
                        {
                            memcpy(userChoiseSet, user_choise.c_str(), user_choise.size());
                            userChoiseSet[user_choise.size()] = '\0';
                            isDefaultUserChoiseSet = true;
                        }
                    }
                    else
                    {
                        fprintf (stdout, "UIAPIClientTest: default user input is empty. Fill correct argument list. Use -h for help\n");
                    }
                    break;
                }
                case 'd':
                {
                    String cancel_download = optarg;
                    if (cancel_download.compare("cancel") == 0)
                    {
                        cancelDownload = true;
                    }
                    break;
                }

                default:
                {
                    //fprintf (stdout, "No valid command line argument. Use -h for help\n");
                    //break;
                }
            }
        }
        while (next_option != -1);
    }
	*/
    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "LEAVE << ProcessCommandLine");
}
//------------------------------------------------------------------------------------------------------
void FinalizeInstance();
//------------------------------------------------------------------------------------------------------
bool StartInstance()
{
    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "ENTER >> StartInstance");

    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "LEAVE << StartInstance. Result: true");
    return true;
}
//------------------------------------------------------------------------------------------------------
void FinalizeInstance()
{
    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "ENTER >> FinalizeInstance");

    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "LEAVE << FinalizeInstance");
}
//------------------------------------------------------------------------------------------------------
int main(int argc, char** argv)
{
/*
     int t_argc = 4;

     char prName[c_max_len];
     memset(prName, '\0', c_max_len);
     memcpy(prName, "Message listener Test", 21);

     char t_i[c_max_len];
     memset(t_i, '\0', c_max_len);
     memcpy(t_i, "-idef_user_choise", 17);

     char t_c[c_max_len];
     memset(t_c, '\0', c_max_len);
     memcpy(t_c, "-cy", 3);

     char t_o[c_max_len];
     memset(t_o, '\0', c_max_len);
     memcpy(t_o, "-oaaa-ccc", 9);

     char* t_argv[5];
     t_argv[0] = prName;
     t_argv[1] = t_i;
     t_argv[2] = t_c;
     t_argv[3] = t_o;
     t_argv[4] = 0;

     //-i def_user_choise -c y -o aaa-ccc
*/
    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "ENTER >> main");

    ProcessCommandLine(argc, argv /*t_argc, t_argv*/);

//    int result;

    if (!StartInstance())
    {
        fprintf(stdout, "UIAPIClientTest: Failed to initialize UI API listener instance");
        exit (EXIT_FAILURE);
    }

    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "create message handler");

    CUIMessageHandler* handler = new CUIMessageHandler(
        isDefaultUserInput ? userInput : ((const char*)0),
        isDefaultUserConfirm ? userConfirm : ((const char*)0),
        isDefaultUserChoiseSet ? userChoiseSet : ((const char*)0),
        cancelDownload ? (&cancelDownload) : ((bool*)0)
    );

    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "Init message handler");

    handler->Init();

    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "create message listener");

    MessageListener* listener = CreateMessageListener(handler);

    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "call WaitMessages()");

    if (listener->WaitMessages() == e_Ok)
    {
        // main daemon cycle
        while (true)
        {
            // do something in cycle
            
			Sleep(500000);
        }

		cout << "After sleep" << endl;

        LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "call StopWaitingMessages()");
        listener->StopWaitingMessages();

		cout << "After Stop Waiting" << endl;
    }

    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "release message listener");

    listener->Release();

    FinalizeInstance();

    fprintf(stdout, "UI API listener stopped");

    LOG_DEBUG_(NS_Logging::GetLogger(c_MessageListenerLog), "LEAVE << main");

    exit(EXIT_SUCCESS);
}
