/* This file is part of the Chakra project

   Copyright (C) 2010 Lukas Appelhans <l.appelhans@gmx.de>

   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 AKABEICLIENTBACKEND_H
#define AKABEICLIENTBACKEND_H

#include <QObject>

#include <akabeiclient_global.h>
#include <akabeiclientdatabasehandler.h>
#include <akabeipackage.h>
#include <akabeibackend.h>
#include <akabeiclientmirrorlist.h>

class QNetworkAccessManager;

namespace AkabeiClient {
class Queue;
class TransactionHandler;
class PolKitSignatureChecker;
/**
 * \class Backend akabeiclientbackend.h "akabeiclientbackend.h"
 *
 * \brief This class is the base class of AkabeiClient.
 *
 * This class is used to be a central place to store global variables/statics.
 *
 * Before the client does anything with the akabei libraries, it needs to initialize it.
 * For this it should call initialize and wait for the status to change to AkabeiCore::Backend::StatusReady.
 *
 * In general when using AkabeiClient, Qt::QueuedConnections should be used when connecting a signal to a slot,
 * otherwise there might be deadlocks.
 *
 * This class is thread-safe.
 */
class AKABEICLIENTSHARED_EXPORT Backend : public QObject
{
    Q_OBJECT
    Q_DISABLE_COPY(Backend)
    public:
        friend class Configuration;

        /**
         * @returns the backend instance
         */
        static Backend *instance();
        virtual ~Backend();

        /**
         * Sets the locale into which this library should be translated
         * @param local a local like "de"
         */
        void setLocale(const QString &locale);

        /**
         * @returns the status the backend currently is in
         */
        Akabei::Backend::Status status() const;

        /**
         * @returns the local database
         */
        DatabaseHandler *localDatabase();

        /**
         * @returns a list of remote databases
         */
        QList<DatabaseHandler*> databases();

        /**
         * @returns a Queue object which gets used by the TransactionHandler
         * This queue needs to get filled with packages each time a transaction is prepared.
         */
        Queue * queue();

        /**
         * @returns a global TransactionHandler object, used every time a client wants to process a transaction
         */
        TransactionHandler * transactionHandler();

        /**
         * @returns a MirrorList object created from the given path
         * This object gets automagically deleted once akabei finishes.
         * @param path the path from which the MirrorList is created (a simple text file)
         */
        MirrorList * mirrorList(const QString &path);

        /**
         * @returns a signature checker to be used by operations etc
         */
        PolKitSignatureChecker * signatureChecker();

        /**
         * @returns the global Akabei(core) Backend, the same as Akabei::Backend::instance()
         */
        Akabei::Backend *backend() const;

    public Q_SLOTS:
        /**
         * This method is used to initialize akabei.
         * @param root the root dir of the new akabei instance, per default read from config file
         * @param cache the cache dir of the new akabei instance, per default read from config file
         * @param dbs the database dir of the new akabei instance, per default read from config file
         */
        void initialize(const QString &root = QString(), const QString &cache = QString(), const QString &dbs = QString(), const QUrl &config = QUrl());

        /**
         * Updates all database from remote sources.
         * @param force force the refresh, even though the file is up to date
         */
        void updateDatabase(bool force = false);

    Q_SIGNALS:
        void statusChanged(Akabei::Backend::Status status);

    private:
        Backend(QObject * parent = 0);
        class Private;
        Private * const d;

        Q_PRIVATE_SLOT(d, void __k__backendStatusChanged(Akabei::Backend::Status))
        Q_PRIVATE_SLOT(d, void __k__dbStatusChanged(AkabeiClient::DatabaseHandler::Status))
        Q_PRIVATE_SLOT(d, void __k__doUpdateDatabase())
};
}

#endif
