/*
    SPDX-FileCopyrightText: 2019 Volker Krause <vkrause@kde.org>

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

#ifndef KPUBLICTRANSPORT_HAFASPARSER_H
#define KPUBLICTRANSPORT_HAFASPARSER_H

#include "kpublictransport_export.h"

#include "hafasattributemap.h"
#include "hafasbackend.h"

#include <KPublicTransport/Feature>
#include <KPublicTransport/Line>
#include <KPublicTransport/Load>
#include <KPublicTransport/Reply>

#include <QString>

#include <span>
#include <vector>

namespace KPublicTransport {

class Location;

/** Common base for the various Hafas response parsers.
 *  @internal only exported for unit tests
 */
class KPUBLICTRANSPORT_EXPORT HafasParser
{
public:
    [[nodiscard]] QString locationIdentifierType() const { return m_locationIdentifierType; }
    void setLocationIdentifierTypes(const QString &idType, const QString &standardIdType = {});
    void setLineModeMap(std::span<HafasLineModeMapEntry> modeMap);
    void setStandardLocationIdentfierCountries(std::vector<uint8_t> &&uicCountryCodes);
    void setAttributeMapName(QStringView attrMap);

    Reply::Error error() const;
    QString errorMessage() const;

    /** Parse Hafas location identifier. */
    [[nodiscard]] Location fromLocationId(const QString &locId) const;

    /** Convert occupancy level. */
    [[nodiscard]] static Load::Category parseLoadLevel(int level);

    [[nodiscard]] HafasAttribute lookupAttribute(QStringView category, QStringView code) const;

    /** Coordinate conversion */
    [[nodiscard]] static double coordHafas2Geo(int hafasCoord) { return hafasCoord / 1000000.0; }
    [[nodiscard]] static int coordGeo2Hafas(double geoCoord) { return (int)(geoCoord * 1000000.0); }

protected:
    HafasParser();
    ~HafasParser();

    void clearErrorState();
    Line::Mode parseLineMode(const QString &modeId) const;
    Line::Mode parseLineMode(const QStringView &modeId) const;
    Line::Mode parseLineMode(int modeId) const;

public:
    /** Set @p id as identifier on @p loc.
     *  If @p id is a valid UIC station code according to the configuration
     *  of the parser, it's also set to the standardLocationIdentifierType.
     */
    void setLocationIdentifier(Location &loc, const QString &id) const;

protected:
    mutable QString m_errorMsg;
    mutable Reply::Error m_error = Reply::NoError;

private:
    Q_DISABLE_COPY(HafasParser)

    QString m_locationIdentifierType;
    QString m_standardLocationIdentifierType;
    std::span<HafasLineModeMapEntry> m_lineModeMap;
    std::vector<uint8_t> m_uicCountryCodes;
    HafasAttributeMap m_attrMap;
};

}

#endif // KPUBLICTRANSPORT_HAFASPARSER_H
