/******************************************************************************\
 *  This sample is supplied as is with no implied warranty.  
 *  It is designed to assist you in using the Cisco AnyConnect VPN API. 
 *  It is assumed that you will build a production application and 
 *  refer to this sample as a reference only.
 \*****************************************************************************/

#ifndef _CLICLIENTIMPL_
#define _CLICLIENTIMPL_

#include <mutex>
#include <stdio.h>
#include <stdlib.h>
#include "ClientIfc.h"

enum RequestType
{ 
    REQ_CONNECT,
    REQ_GROUPLIST,
    REQ_STATE,
    REQ_STATISTICS,
    REQ_DISCONNECT,
    REQ_END
};

/**
 * This is an example application demonstrating the implementation of the
 * AnyConnect API
 */

class CLIClientImpl : public ClientIfc
{
    public:

        CLIClientImpl();
        virtual ~CLIClientImpl();

        // The following methods are for support and not considered part of
        // the main API interface.

        void printHostList();

        void printDefaultHost();

        void connect(std::string host, std::string user,
                     std::string password, std::string group);

        void disconnect();

        void showGroups(std::string host);

        /**
         * This method demonstrates accessing the statistics data delivered
         * via the ClientIfc::StatsCB method.
         */
        void getStats();

        /**
         * Method with example of parsing ConnectPromptInfo.
         *
         * This method is triggered by an API call on the method
         * UserPromptCB(ConnectPromptInfo &).
         */
        void setUserData(ConnectPromptInfo &ConnectPrompt);

        void printGroupList(ConnectPromptInfo &ConnectPrompt);

        std::wstring convertMultiByteToWide(const std::string &sInputData);

        void EventAvailable();
        void ProcessEvents();

        void SetRequestType(RequestType e_RequestType);

    protected:

        void StatsCB(VPNStats &stats);

        void StateCB(const VPNState state,
                     const VPNSubState subState,
                     const tstring stateString);

        void BannerCB(const tstring &banner);

        void PreConnectReminderCB(const tstring &rtstrPreConnectReminder);

        void NoticeCB(const tstring &notice,
                      const MessageType type,
                      const bool bSensitive = false);

        void ExitNoticeCB(const tstring &notice,
                          const int returnCode);

        void ServiceReadyCB();

        void UserPromptCB(ConnectPromptInfo &ConnectPrompt);

        void CertBlockedCB(const tstring &rtstrUntrustedServer);
        void CertWarningCB(const tstring &rtstrUntrustedServer,
                           const std::list<tstring> &rltstrCertErrors,
                           bool bAllowImport);


    private:

        RequestType me_RequestType;

        tstring ms_user,
                ms_pswd,
                ms_group;

        std::mutex mtx;
        volatile bool mb_exit;
        volatile bool mb_eventAvailable;
        bool mb_ConnectingStateReceived;
};


#endif // _CLICLIENTIMPL_
