#pragma once

#ifndef WMC_SESSION__H
#define WMC_SESSION__H

#include "session_factory.h"

#include <string>
#include <vector>

#include <util/generic/ptr.h>

#include <Poco/Data/Session.h>

#include <wmconsole/legacy/util/mysql_url.h>

namespace NWebmaster {
class Iterator;

/*
  Encapsulates multiple Poco::Data::Session objects to support use
  of multiple host databases.
 */
class WMCHostsSession {
public:
    WMCHostsSession(const std::string &dbkey, const std::string &url);
    WMCHostsSession(const std::string &dbkey, const std::vector<std::string> &urlList);
    virtual ~WMCHostsSession() {}

    Iterator getHostDbIterator(int i = 0) const;
    static Iterator getPartitionIterator(int i = 0);

    virtual Poco::Data::Session &getHostSessionByName(const std::string &hostname) const;
    virtual Poco::Data::Session &getHostSession(int id) const;

    size_t size() const {
        return getHostDbCount();    // NVI idiom used
    }
    int getHostDbId(const std::string &hostname) const;

    virtual size_t getHostDbCount() const;

private:
    WMCHostsSession(const WMCHostsSession &);
    WMCHostsSession &operator = (const WMCHostsSession &);
    std::vector<NWebmaster::SessionProxy> hostSessions;
};


/*
  Encapsulates multiple Poco::Data::Session objects to support use
  of multiple host databases and one user database.
 */
class WMCSession : public WMCHostsSession {
public:
    typedef TAtomicSharedPtr<WMCSession> Ptr;

    WMCSession(const std::string &dbkey, const std::string &userUrl, const std::vector<std::string> &hostUrlList);

    Poco::Data::Session &getUserSession();
    Poco::Data::Session &getHostSession(int id) const override;
    size_t getHostDbCount() const override;

private:
    Poco::Data::Session userSession;
};

/*
  Lists all integers in range from 0 to m-1 starting from i.
 */
class Iterator {
public:
    Iterator(int i, int m);

    bool next();
    int get() const;

private:
    int start;
    int max;
    int current;
};

} // namespace NWebmaster

#endif //WMC_SESSION__H
