#ifndef JobInterface_h
#define JobInterface_h

/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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.
*
* This software is distributed in the hope that it will be useful, but WITHOUT
* Any WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program.  If not, see <http://www.gnu.org/licenses/>.
*
*******************************************************************************/

#include "JobCommand.h"
#include "Debug.h"
#include "Job.h"
#include "MessageBuffer.h"
#include "UserSet.h"

#include <QHash>
#include <QObject>
#include <QProcess>
#include <QString>

class CustomProcess;
class JobThread;

//* Job managment
class JobInterface:public QObject, private Base::Counter<JobInterface>
{

    //* Qt meta object declaration
    Q_OBJECT

    public:

    //* constructor
    explicit JobInterface( QObject* parent = nullptr );

    Q_SIGNALS:

    //* emitted when job list is available
    void jobListReady( Job::Set );

    //* emitted when user list is available
    void userListReady( UserSet );

    //* command completed
    void commandCompleted( JobCommand );

    //* emitted when there is no more commands in pile
    void ready();

    //* message
    void messageAvailable( const QString& );

    public Q_SLOTS:

    //* add command
    void addCommand( JobCommand );

    private Q_SLOTS:

    //* error from process
    void _error( QProcess::ProcessError );

    //* take action when current command completed
    void _commandCompleted( int = 0, QProcess::ExitStatus = QProcess::NormalExit );

    //* read on-fly from process
    void _readStdout();

    //* read on-fly from process
    void _readStderr();

    protected:

    //* process job set (using top)
    void _processJobList();

    //* reset buffers
    void _resetBuffers();

    //* run next command in pile
    bool _runCommand();

    //* reset process
    void _resetProcess();

    //* process
    bool _hasProcess() const
    { return process_; }

    //* create new process to run command
    CustomProcess& _newProcess();

    //* process
    CustomProcess& _process() const
    { return *process_; }

    //* convert string number (using k, M, G) into a number
    static qint64 _memoryStringToInteger( const QString& value );

    //* convert string time into a number
    static qint64 _cpuTimeToInteger( const QString& value );

    private:

    //* custom process
    CustomProcess* process_ = nullptr;

    //* thread
    JobThread* thread_ = nullptr;

    //* stdout buffer
    MessageBuffer stdoutBuffer_;

    //* stderr buffer
    MessageBuffer stderrBuffer_;

    //* map command type to name
    JobCommand::List commands_;

};

#endif
