#ifndef QPID_PLUGIN_H
#define QPID_PLUGIN_H

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 "qpid/shared_ptr.h"
#include <boost/noncopyable.hpp>
#include <vector>
#include <boost/function.hpp>


/**@file Generic plug-in framework. */

namespace qpid {
class Options;

/**
 * Plug-in base class.
 */
class Plugin : boost::noncopyable
{
  public:
    /**
     * Base interface for targets that receive plug-ins.
     *
     * The Broker is a plug-in target, there might be others
     * in future.
     */
    struct Target { virtual ~Target() {} };

    typedef std::vector<Plugin*> Plugins;
    
    /**
     * Construct registers the plug-in to appear in getPlugins().
     * 
     * A concrete Plugin is instantiated as a global or static
     * member variable in a library so it is registered during static
     * initialization when the library is loaded.
     */
    Plugin();
    
    virtual ~Plugin();

    /**
     * Configuration options for the plugin.
     * Then will be updated during option parsing by the host program.
     * 
     * @return An options group or 0 for no options. Default returns 0.
     * Plugin retains ownership of return value.
     */
    virtual Options* getOptions();

    /**
     * Initialize Plugin functionality on a Target.
     * 
     * Plugins should ignore targets they don't recognize.
     */
    virtual void initialize(Target&) = 0;

    /** List of registered Plugin objects.
     * Caller must not delete plugin pointers.
     */
    static const Plugins& getPlugins();

  private:
    static Plugins plugins;
};
 
} // namespace qpid

#endif  /*!QPID_PLUGIN_H*/
