#ifndef __ARC_SERVICE_H__
#define __ARC_SERVICE_H__

#include <arc/ArcConfig.h>
#include <arc/Logger.h>
#include <arc/message/MCC.h>
#include <arc/loader/Plugin.h>
#include <arc/message/SecHandler.h>

namespace Arc {

/// Service - last component in a Message Chain.
/**  This class which defines interface and common functionality for every
 Service plugin. Interface is made of method process() which is called by
 Plexer or MCC class.
  There is one Service object created for every service description
 processed by Loader class objects. Classes derived from Service class
 must implement process() method of MCCInterface.
  It is up to developer how internal state of service is stored and
 communicated to other services and external utilities.
  Service is free to expect any type of payload passed to it and generate
 any payload as well. Useful types depend on MCCs in chain which leads to
 that service. For example if service is expected to by linked to SOAP
 MCC it must accept and generate messages with PayloadSOAP payload.
  Method process() of class derived from Service class may be called
 concurrently in multiple threads. Developers must take that into account
 and write thread-safe implementation.
  Simple example of service is provided in /src/tests/echo/echo.cpp of
 source tree.
  The way to write client counterpart of corresponding service is
 undefined yet. For example see /src/tests/echo/test.cpp .
 */
class Service: public MCCInterface
{
    protected:
        /** Set of labelled authentication and authorization handlers.
        MCC calls sequence of handlers at specific point depending
        on associated identifier. in most aces those are "in" and "out"
        for incoming and outgoing messages correspondingly. */
        std::map<std::string,std::list<ArcSec::SecHandler*> > sechandlers_;

        /** Logger object used to print messages generated by this class. */
        static Logger logger;

        /** Is service valid? Services which are not valid should set this
         * to false in their constructor. */
        bool valid;

        /** Executes security handlers of specified queue.
          For more information please see description of MCC::ProcessSecHandlers */
        MCC_Status ProcessSecHandlers(Message& message,const std::string& label = "") const;

    public:
        /** Example constructor - Server takes at least its configuration subtree */
        Service(Config*, PluginArgument* arg);

        virtual ~Service(void) { };

        /** Add security components/handlers to this MCC.
          For more information please see description of MCC::AddSecHandler */
        virtual void AddSecHandler(Config *cfg,ArcSec::SecHandler* sechandler,const std::string& label = "");

        /** Service may implement own service identifier gathering method.
           This method return identifier of service which is used for registering
           it Information Services. */
        virtual std::string getID() { return ""; };

        /** Returns true if the Service is valid. */
        operator bool() const { return valid; };
        /** Returns true if the Service is not valid. */
        bool operator!() const { return !valid; };
};

#define ServicePluginKind ("HED:SERVICE")

class ServicePluginArgument: public PluginArgument {
    private:
        Config* config_;
        ChainContext* context_;
    public:
        ServicePluginArgument(Config* config,ChainContext* context):config_(config),context_(context) { };
        virtual ~ServicePluginArgument(void) { };
        operator Config* (void) { return config_; };
        operator ChainContext* (void) { return context_; };
};

} // namespace Arc

#endif /* __ARC_SERVICE_H__ */
