/***************************************************************************
                              qgswfsserver.sip
                              -------------------
  begin                : May 2, 2015
  copyright            : (C) 2015 by Alessandro Pasotti
  email                : a dot pasotti at itopen dot it
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program 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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef QGSWFSSERVER_H
#define QGSWFSSERVER_H

#include <QDomDocument>
#include <QMap>
#include <QString>
#include <map>
#include "qgis.h"
#include "qgsowsserver.h"
#include "qgsvectorlayer.h"
#include "qgswfsprojectparser.h"

class QgsCoordinateReferenceSystem;
class QgsComposerLayerItem;
class QgsComposerLegendItem;
class QgsComposition;
class QgsFields;
class QgsMapLayer;
class QgsPoint;
class QgsRasterLayer;
class QgsConfigParser;
class QgsVectorLayer;
class QgsCoordinateReferenceSystem;
class QgsField;
class QgsFeature;
class QgsRectangle;
class QgsGeometry;
class QgsSymbol;
class QgsRequestHandler;
class QFile;
class QFont;
class QImage;
class QPaintDevice;
class QPainter;


/** This class handles all the wms server requests. The parameters and values have to be passed in the form of
a map<QString, QString>. This map is usually generated by a subclass of QgsWMSRequestHandler, which makes QgsWFSServer
independent from any server side technology*/

class QgsWfsServer: public QgsOWSServer
{
  public:
    /** Constructor. Takes parameter map and a pointer to a renderer object (does not take ownership)*/
    QgsWfsServer( const QString& configFilePath, QMap<QString, QString>& parameters, QgsWfsProjectParser* cp,
                  QgsRequestHandler* rh, const QgsAccessControl* accessControl );
    ~QgsWfsServer();

    void executeRequest() override;

    /** Returns an XML file with the capabilities description (as described in the WFS specs)*/
    QDomDocument getCapabilities();

    /** Returns an XML file with the describe feature type (as described in the WFS specs)*/
    QDomDocument describeFeatureType();

    /** Creates a document that describes the result of the getFeature request.
       @return 0 in case of success*/
    int getFeature( QgsRequestHandler& request, const QString& format );

    /** Read and apply the transaction
       @return 0 in case of success*/
    QDomDocument transaction( const QString& requestBody );

    /** Sets configuration parser for administration settings. Does not take ownership*/
    void setAdminConfigParser( QgsWfsProjectParser* parser ) { mConfigParser = parser; }

  private:
    /** Don't use the default constructor*/
    QgsWfsServer();

    /** Get service address from REQUEST_URI if not specified in the configuration*/
    QString serviceUrl() const;

    /* The Type of Feature created */
    QString mTypeName;
    /* The list of Feature's Type requested */
    QStringList mTypeNames;
    QString mPropertyName;
    bool mWithGeom;
    /* Error messages */
    QStringList mErrors;

    QgsWFSProjectParser* mConfigParser;

  protected:

    void startGetFeature( QgsRequestHandler& request, const QString& format, int prec, QgsCoordinateReferenceSystem& crs, QgsRectangle* rect );
    void setGetFeature( QgsRequestHandler& request, const QString& format, QgsFeature* feat, int featIdx, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes, const QSet<QString>& excludedAttributes );
    void endGetFeature( QgsRequestHandler& request, const QString& format );

    //method for transaction
    QgsFeatureIds getFeatureIdsFromFilter( const QDomElement& filter, QgsVectorLayer* layer );

    //methods to write GeoJSON
    QString createFeatureGeoJSON( QgsFeature* feat, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes, const QSet<QString>& excludedAttributes ) /*const*/;

    //methods to write GML2
    QDomElement createFeatureGML2( QgsFeature* feat, QDomDocument& doc, int prec, QgsCoordinateReferenceSystem& crs, const QgsAttributeList& attrIndexes, const QSet<QString>& excludedAttributes ) /*const*/;

    //methods to write GML3
    QDomElement createFeatureGML3( QgsFeature* feat, QDomDocument& doc, int prec, QgsCoordinateReferenceSystem& crs, QgsAttributeList attrIndexes, QSet<QString> excludedAttributes ) /*const*/;

    void addTransactionResult( QDomDocument& responseDoc, QDomElement& responseElem, const QString& status, const QString& locator, const QString& message );
};

#endif