/**
 * Copyright (C) 2023-2026 Linaro Limited (or its affiliates). All rights reserved.
 * Copyright (C) 2012-2023 Arm Limited (or its affiliates).
 * All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */

#ifndef TERMINAL_H
#define TERMINAL_H

#ifdef Q_OS_WIN
#include <QIODevice>
#else
#include <QLocalSocket>
#endif
#include <QProcess>
#include "qringbuffer_p.h"
#include "lgpl_gui_export.h"

class QTextDecoder;
class TerminalProcess;
#ifdef Q_OS_WIN
class LGPL_GUI_EXPORT Terminal : public QIODevice
#else
class LGPL_GUI_EXPORT Terminal : public QLocalSocket
#endif
{
    Q_OBJECT
public:
    explicit Terminal(QObject *parent = 0);
    ~Terminal();
    void setWindowSize(int columns, int rows);
    int rows() const;
    int columns() const;
    bool openManager();
#ifndef Q_OS_WIN
    int openSubordinate();
#endif
    virtual qint64 bytesAvailable() const override;

    virtual bool atEnd() const override;
    virtual bool isSequential() const override;
public slots:
    void pushBytes(const QByteArray& bytes);
signals:
    void windowSizeChanged(int columns, int rows);
    void processStarted(const QString &commandLine);
    void processFinished(int exitCode, QProcess::ExitStatus exitStatus);
protected:
    virtual qint64 readData(char*, qint64) override;
#ifdef Q_OS_WIN
    virtual qint64 writeData(const char*, qint64);
#endif
private:
    void emitProcessStarted(const QString& commandLine);
    void emitProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
    void setProcess(QProcess *process);
    void winch();

#ifndef Q_OS_WIN
    int mManagerFd;
    const char *mPtsName;
#endif
    QProcess *mCurrentProcess;
    DDTRingBuffer mPushedBytes;
    int mColumns;
    int mRows;
friend class TerminalProcess;
};

#endif // TERMINAL_H
