/*
SPDX-FileCopyrightText: 2002-2004 Otto Bruggeman <otto.bruggeman@home.nl>
SPDX-FileCopyrightText: 2010 Kevin Kofler <kevin.kofler@chello.at>

SPDX-License-Identifier: GPL-2.0-or-later
*/

#ifndef DIFF2_PARSERBASE_H
#define DIFF2_PARSERBASE_H

#include <QRegExp>

#include "kompare.h"
#include "difference.h"

class QStringList;
class QString;

namespace Diff2
{

class KompareModelList;
class DiffModelList;
class DiffModel;

class ParserBase
{
public:
    ParserBase(const KompareModelList* list, const QStringList& diff);
    virtual ~ParserBase();

    static QString escapePath(QString path);
    static QString unescapePath(QString path);

public:
    enum Kompare::Format format() { return determineFormat(); };
    DiffModelList* parse(bool* malformed = nullptr);

protected:
    virtual bool parseContextDiffHeader();
    virtual bool parseEdDiffHeader();
    virtual bool parseNormalDiffHeader();
    virtual bool parseRCSDiffHeader();
    virtual bool parseUnifiedDiffHeader();

    virtual bool parseContextHunkHeader();
    virtual bool parseEdHunkHeader();
    virtual bool parseNormalHunkHeader();
    virtual bool parseRCSHunkHeader();
    virtual bool parseUnifiedHunkHeader();

    virtual bool parseContextHunkBody();
    virtual bool parseEdHunkBody();
    virtual bool parseNormalHunkBody();
    virtual bool parseRCSHunkBody();
    virtual bool parseUnifiedHunkBody();

    virtual DiffModelList* parseContext();
    virtual DiffModelList* parseEd();
    virtual DiffModelList* parseNormal();
    virtual DiffModelList* parseRCS();
    virtual DiffModelList* parseUnified();

protected: // Helper methods to speed things up
    bool matchesUnifiedHunkLine(const QString& line) const;
    void checkHeader(const QRegExp& header);

protected:
    /** What is format of the diff */
    virtual enum Kompare::Format determineFormat();

protected:
    // Regexps for context parsing
    QRegExp m_contextDiffHeader1;
    QRegExp m_contextDiffHeader2;

    QRegExp m_contextHunkHeader1;
    QRegExp m_contextHunkHeader2;
    QRegExp m_contextHunkHeader3;

    QRegExp m_contextHunkBodyRemoved;
    QRegExp m_contextHunkBodyAdded;
    QRegExp m_contextHunkBodyChanged;
    QRegExp m_contextHunkBodyContext;
    QRegExp m_contextHunkBodyLine; // Added for convenience

    // Regexps for normal parsing
    QRegExp m_normalDiffHeader;

    QRegExp m_normalHunkHeaderAdded;
    QRegExp m_normalHunkHeaderRemoved;
    QRegExp m_normalHunkHeaderChanged;

    QRegExp m_normalHunkBodyRemoved;
    QRegExp m_normalHunkBodyAdded;
    QRegExp m_normalHunkBodyDivider;

    enum Difference::Type m_normalDiffType;

    // RegExps for rcs parsing
    QRegExp m_rcsDiffHeader;

    // Regexps for unified parsing
    QRegExp m_unifiedDiffHeader1;
    QRegExp m_unifiedDiffHeader2;

    QRegExp m_unifiedHunkHeader;

    QRegExp m_unifiedHunkBodyAdded;
    QRegExp m_unifiedHunkBodyRemoved;
    QRegExp m_unifiedHunkBodyContext;
    QRegExp m_unifiedHunkBodyLine; // Added for convenience

protected:
    const QStringList&         m_diffLines;
    DiffModel*                 m_currentModel;
    DiffModelList*             m_models;
    QStringList::ConstIterator m_diffIterator;

    bool                       m_singleFileDiff;
    bool                       m_malformed;

protected:
    const KompareModelList* m_list;
};

} // End of namespace Diff2

#endif
