#include "filedb/filedb_device.h"

#include <tango/tango.h>

#ifndef TANGO_MAKE_VERSION
  #define TANGO_MAKE_VERSION(major, minor, patch) ((major) * 10000 + (minor) * 100 + (patch))
#endif // !TANGO_MAKE_VERSION

#ifndef TANGO_VERSION
  #define TANGO_VERSION TANGO_MAKE_VERSION(TANGO_VERSION_MAJOR, TANGO_VERSION_MINOR, TANGO_VERSION_PATCH)
#endif // !TANGO_VERSION

#if TANGO_VERSION >= TANGO_MAKE_VERSION(10, 3, 0)

class DServerImpl : public Tango::DServer
{
  public:
    DServerImpl(Tango::DeviceClass *cl_ptr,
                const std::string &name,
                const std::string &desc,
                Tango::DevState state,
                const std::string &status) :
        DServer(cl_ptr, name.c_str(), desc.c_str(), state, status.c_str())
    {
    }

  private:
    void class_factory() override
    {
        add_class(FileDb::FileDbDeviceClass::init("FileDbDevice"));
    }
};

Tango::DServer *constructor(Tango::DeviceClass *cl_ptr,
                            const std::string &name,
                            const std::string &desc,
                            Tango::DevState state,
                            const std::string &status)
{
    return new DServerImpl(cl_ptr, name, desc, state, status);
}

#else

void Tango::DServer::class_factory()
{
    add_class(FileDb::FileDbDeviceClass::init("FileDbDevice"));
}

#endif

int main(int argc, char *argv[])
{
    Tango::Util::_UseDb = false;
    FileDb::DatabaseDeviceClass::db_name.append(argv[1]);

    try
    {
        Tango::Util *tg = Tango::Util::init(argc, argv);
#if TANGO_VERSION >= TANGO_MAKE_VERSION(10, 3, 0)
        tg->register_dserver_constructor(&constructor);
#endif
        tg->server_init();
        for(auto *device_class : *tg->get_class_list())
        {
            auto *db_class = dynamic_cast<FileDb::DatabaseDeviceClass *>(device_class);
            if(db_class)
            {
                db_class->initialise_database();
            }
        }

        TANGO_LOG << "Ready to accept request" << std::endl;
        tg->get_orb()->run();
    }
    catch(const Tango::DevFailed &ex)
    {
        Tango::Except::print_exception(ex);
    }

    return 0;
}
