/***************************************************************************
                          chathistorywriter.h  -  chat logs writer
                             -------------------
    begin                : Tue Jul 13 2010
    copyright            : (C) 2010 by Valerio Pilo
    email                : valerio@kmess.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program 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; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef CHATHISTORYWRITER_H
#define CHATHISTORYWRITER_H

#include <QFile>
#include <QtCore/QObject>


/**
 * Maximum log file size, 4MB.
 */
const long MAX_LOG_FILE_SIZE = 4L * 1024L * 1024L;


// Forward declarations
class ChatMessage;
class ChatMessageStyle;
class Conversation;



/**
 * Class to incrementally save a chat log in XML format to file.
 *
 * Every time a message arrives or is sent, it is parsed into XML and stored here.
 *
 * low level description:
 * As soon as a chat is opened, the xml log saving system choses a file name where
 * to store the log.
 * A quint64 pointer keeps track of the position in the file where to add new data.
 * When writing anything to the file, if the pointer is 0 a file header gets added;
 * then, if it is the first write of the chat, a first conversation tag is added with
 * the time of the first message and the pointer is set to the end of that data; then
 * the new data is written; finally, the XML conversation and messsageRoot closing tags
 * are also added. To ensure integrity, the file is flushed on every write.
 *
 * medium level description:
 * When someone sends a message, we store its XML into a cache, and also flush it into
 * the file, writing from the file pointer position.
 * When another message needs to be stored, we store its XML too into a cache, then flush
 * to the logfile a messagegroup tags pair, containing all previously stored XML messages,
 * and finally we check if it's applicable for message grouping:
 *  - if it is, do nothing (we'll continue stacking up messages for the group)
 *  - If it is not, empty the cache and set the pointer to the end of the written
 *    messageGroup tags. We'll start with a new message or group.
 * As soon as the chat is closed, the file is already filled up and we can just close it.
 *
 * high level description:
 * a class (keeping the logging state) is instantiated. a startLogging( handle ) method is
 * called as soon as the chat is opened.
 * When a message arrives, a logMessage( ChatMessage* ) method is called.
 * When the chat is closed, an endLogging() method is called.
 *
 * @author Valerio Pilo <valerio@kmess.org>
 */
class ChatHistoryWriter : public QObject
{
  Q_OBJECT

  friend class ChatHistoryManager;


  private: // Private constructor

    // Constructor
    ChatHistoryWriter( const QString& account, const QString& handle );


  public: // Public destructor

    // Destructor
    virtual ~ChatHistoryWriter();


  public: // Public methods

    // Return whether the writer is capable of writing new messages
    bool isReady() const;
    // Write a message to file
    void logMessage( const ChatMessage& message );


  private: // Private methods

    // Write the cache contents to the file
    void writeCache();


  private: // Private properties

    // Conversation data, used for chat history manager data caching
    Conversation* conversation_;
    // Handle of the initial contact of the chat being logged
    QString handle_;
    // Whether at least one message was written to the file
    bool isFirstMessage_;
    // Whether the log file was created just for the chat being logged
    bool isNewLogFile_;
    // The last received message, to avoid storing duplicates (not using the cache since it gets cleared often)
    ChatMessage* lastMessage_;
    // Log file where to save the chat
    QFile logFile_;
    // List of messages currently being processed
    QList<ChatMessage> messageCache_;
    // The chat style converter, used to turn chat messages into XML
    ChatMessageStyle* messageStyle_;
    // Last appending position within the file
    qint64 pointer_;

};

#endif // CHATHISTORYWRITER_H
