// SPDX-License-Identifier: LGPL-2.1-or-later
//
// SPDX-FileCopyrightText: 2016 Akshat Tandon <akshat.tandon@research.iiit.ac.in>
//

#include "TagsFilter.h"

#include <QStringList>

#include "GeoDataDocument.h"
#include "GeoDataObject.h"
#include "GeoDataPlacemark.h"

namespace Marble
{

TagsFilter::TagsFilter(GeoDataDocument *document, const Tags &tagsList, FilterFlag filterFlag)
    : m_accepted(new GeoDataDocument)
{
    for (GeoDataFeature *feature : document->featureList()) {
        if (const auto placemark = geodata_cast<GeoDataPlacemark>(feature)) {
            bool acceptPlacemark = false;
            auto const &osmData = placemark->osmData();

            if (filterFlag == FilterRailwayService && osmData.containsTagKey(QStringLiteral("railway")) && osmData.containsTagKey(QStringLiteral("service"))) {
                acceptPlacemark = false;
            } else {
                for (auto const &tag : tagsList) {
                    bool contains;
                    if (tag.second == QLatin1StringView("*")) {
                        contains = osmData.containsTagKey(tag.first);
                    } else {
                        contains = osmData.containsTag(tag.first, tag.second);
                    }
                    if (contains) {
                        acceptPlacemark = true;
                        break;
                    }
                }
            }

            if (acceptPlacemark) {
                m_accepted->append(placemark->clone());
            } else {
                m_rejectedObjects.append(placemark->clone());
            }
        } else {
            m_accepted->append(feature->clone());
        }
    }
}

TagsFilter::~TagsFilter()
{
    delete m_accepted;
    qDeleteAll(m_rejectedObjects);
}

QList<GeoDataFeature *>::const_iterator TagsFilter::rejectedObjectsBegin() const
{
    return m_rejectedObjects.begin();
}

QList<GeoDataFeature *>::const_iterator TagsFilter::rejectedObjectsEnd() const
{
    return m_rejectedObjects.end();
}

GeoDataDocument *TagsFilter::accepted()
{
    return m_accepted;
}

void TagsFilter::removeAnnotationTags(GeoDataDocument *document)
{
    for (auto placemark : document->placemarkList()) {
        OsmPlacemarkData &osmData = placemark->osmData();
        removeAnnotationTags(osmData);
        for (auto &reference : osmData.hRef()->nodeReferences()) {
            removeAnnotationTags(reference);
        }
        for (auto &reference : osmData.hRef()->memberReferences()) {
            removeAnnotationTags(reference);
        }
    }
}

void TagsFilter::removeAnnotationTags(OsmPlacemarkData &osmData)
{
    osmData.removeTag(QStringLiteral("comment"));
    osmData.removeTag(QStringLiteral("note"));
    osmData.removeTag(QStringLiteral("note:de"));
    osmData.removeTag(QStringLiteral("fixme"));
    osmData.removeTag(QStringLiteral("todo"));
    osmData.removeTag(QStringLiteral("source"));
    osmData.removeTag(QStringLiteral("source:geometry"));
    osmData.removeTag(QStringLiteral("source:name"));
    osmData.removeTag(QStringLiteral("source:addr"));
    osmData.removeTag(QStringLiteral("source:ref"));
    osmData.removeTag(QStringLiteral("source_ref"));
}

}
