/* Network-Integrated Multimedia Middleware (NMM)
 * http://www.motama.com/nmm.html
 *
 * Copyright (C) 2006-2007
 * Motama GmbH, Saarbruecken, Germany
 * http://www.motama.com
 *
 * This file is part of NMM. 
 * 
 * NMM is free software; you can redistribute it and/or modify it    
 * under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; only version 2 of the License.      
 * 
 * NMM 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 General Public License 
 * along with NMM; if not, write to the Free Software Foundation,    
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#ifndef NMM_HTTPPROTOCOLREADER_HPP
#define NMM_HTTPPROTOCOLREADER_HPP NMM_HTTPPROTOCOLREADER_HPP

#include "ProtocolReader.hpp"

namespace NMM {

  /**
   * \brief This is an derived class from the ProtocolReader which implements
     HTTP communication including comminication with SHOUTCast servers.

     The class opens a socket to the host specified and sends a GET
     request. After that, it parses the header fields and saves
     content data already read. When it has to read the content, it
     first eventually copies the saved data and then reads the missing
     amount from the socket.
   */
  class HTTPProtocolReader : public ProtocolReader {

  private:
    //! member to save content, already read but not delivered
    char* cache_buffer;
    //! member to save content, already read but not delivered
    char* cache_buffer_ptr;
    //! member to save size of content, already read but not delivered
    size_t cache_buffer_size;
    //! member to save the target host
    string host;
    //! member to save the target host port
    int port;
    //! member to save the target uri on the host
    string uri;
    //! member to save the socket descriptor for the contacted host
    int socketd;
    //! member to save the title of the stream if provided, else the uri
    string title;
    //! member to save the content-type of the data as specified by the meta-data, NO CONTENT-PARSING!
    string content_type;
    //! member to save the content-length of the data if specified in the meta data
    int content_length;


    /**
     * this method initialized the server socket to communicate with the HTTP-Server.
       \returns true iff the socket could be initialized successfully.
     */
    bool prepareSocket();

    /**
     * this method writes the specified data to the ProtocolReader's socket.
       \param data: the data to write.
       \returns true iff the read was successful.
     */
    bool writeSocket(const string data);

    /**
     * this method computes the HTTP request from the internal members of the HTTPProtocolReader.
       \returns the HTTP request.
     */
    string computeRequest();

    /**
     * this method parses HTTP/icecast header data for a specific header field.
       \param data: the header data to parse.
       \param header: the header field to parse for.
       \param value: the value, assoziated with that header field.
       \returns true iff the header field was found.
     */
    bool parseHeader(const string data, const string header, string& value);

    /**
     * this method parses HTTP/icecast header data for a specific header field.
       \param data: the header data to parse.
       \param header: the header field to parse for.
       \param value: the value, assoziated with that header field.
       \returns true iff the header field was found.
     */
    bool parseHeader(const string data, const string header, int& value);

  protected:

    /**
     * this method parses a  URL and initializezed the members for the ProtocolReader.
       \param url: the url to parse.
       \returns true iff the given url is valid for this Reader.
     */
    virtual bool parseURL(const string url);

    /**
     * this method initializes the ProtocolReader from the members, set by parseURL.
       \returns true iff the Reader could be initialized.
     */
    virtual bool init();

  public:
    /**
     * The constructor.
       \param parent: the pointer to the calling Node.
       \param name: the name of the ProtocolReader.
     */
    HTTPProtocolReader(Node* parent, const string name = "HTTPProtocolReader");
    /**
     * The default destructor.
     */
    virtual ~HTTPProtocolReader();

    /**
     * this method reads the specific amount of data in a given char*.
       \param data: the pointer, where to write the read data to.
       \param amount: the amount of data in bytes.
       \returns true iff the operation was successful.
     */
    virtual int readData(char* data, size_t amount);

    /**
     * this method returns the NMM type/subtype of the media format 
       \return the format
     */
    string getMediaFormat();

  };
} /* namespace NMM */

#endif //NMM_HTTPPROTOCOLREADER_HPP
