#ifndef __TNURL_STATISTICS_H__
#define __TNURL_STATISTICS_H__

#include "TnUrl.h"
#include "foundation/Mutex.h"
#include "foundation/SharedPtr.h"

#include <map>
#include <string>
#include <ctime>
#include <vector>
#include <boost/circular_buffer.hpp>
//#include <boost/shared_ptr.hpp>

namespace Tn
{
    namespace Url
    {
        class DefaultUrl;
    }
}

class TnUrlStatistics
{
public:
    // Transfer record
    struct TxRecord
    {
        unsigned int id;
        std::string url;
        TnUrl::ErrorCode error;
        long responseCode;
        double totalTime;
        double sizeDownload;
        double speedDownload;
        double sizeUpload;
        double speedUpload;
        time_t timestamp;
        TxRecord();
        //TxRecord(std::string const & url_, TnUrl::ErrorCode error_, long responseCode_, double totalTime_, double sizeDownload_, double speedDownload_, time_t timestamp_);
        static bool isErrorRecord(const TxRecord & record);
    };
    
public:
    // Singleton 
    static Tn::Foundation::shared_ptr<TnUrlStatistics> GetInstance();
    
    // Return current number of active URL requests
    size_t Requests() const;
    
    // Return total number of bytes transferred so far
    double BytesTransferred() const;
    
    // Return rough judgment of network status
    bool NetworkReachable() const;
    
    // Sets the maximum size of the request buffer
    void SetRequestBufferSize(size_t size);
    
    // Gets the current request buffer
    std::vector<TxRecord> RequestBuffer() const;

private:
    TnUrlStatistics();

    // Should only be called by DefaultUrl:

    // Singleton (non-const)
	static Tn::Foundation::shared_ptr<TnUrlStatistics> PrivateInstance();
    
    // Record the beginning of a URL request
    void Begin(void* key, std::string const & url);
    
    // Record the end of a URL request
    void End(void* key, std::string const & url, TnUrl::ErrorCode error, long responseCode, const std::vector<double>& statisticsData);
    
    friend class Tn::Url::DefaultUrl;
    
private:
    // Mutex for member access
    mutable Tn::Foundation::mutex m_mutex;
    // Requests currently in progress
    std::map<void*, std::string> m_requestsInProgress;
    
    // Total number of bytes transferred so far
    double m_bytesTransferred;
    
    // Circular buffer of transfer records
    boost::circular_buffer<TxRecord> m_records;
    
    // Rough judgment of network status
    bool m_networkReachable;
    
    // Singleton instance
    static Tn::Foundation::shared_ptr<TnUrlStatistics> m_pInstance;
};

#endif
