#ifndef _GRPCACCESS_H_
#define _GRPCACCESS_H_

#include "config.h"

#include <Client/ClientUtils/IntersectionParameters.hpp>
#include <Client/ClientUtils/Network/NetworkInterface.h>
#include <Client/ClientUtils/mesh_simplification_parameters.hpp>
#include <Client/ClientUtils/shift_parameters.hpp>
#include <Client/ClientUtils/tiling_parameters.hpp>
#include <Client/ClientUtils/writer_options.hpp>
#include <GSTenums.h>
#include <buildspec.h>

#include <cstdint>

namespace GST
{
namespace ClientUtils
{

class GST_API_EXPORT GRPCAccess : public NetworkInterface
{
public:
	GRPCAccess(HostPtr host);
	~GRPCAccess();

	bool isConnected() const override;

	void connect() override;

	void disconnect() override;

	bool isSSLUsed() const override;

	NetworkPtr fork() const override;

	NetworkPtr reconnect(const std::string &user,
						 const std::string &pwd,
						 const std::string &db = "") const override;

	bool isSuperUserConnection() const override;

	UserPtr getCurrentGSTUser() const override;

	std::string getEndPointName() const override;

	std::string getUserName() const override;

	EndPointPtr getEndPoint() const override;

	BackendType GetBackendType() const override;

	ServerInfoPtr GetServerInformation() override;

	DataTablePtr GetServerInformationTable() const override;

	bool TableIsSelectable(const std::string &fullTableName) const override;

	bool ColumnExistInTable(const std::string &fullTableName,
							const std::string &columnName) const override;

	NamesListPtr ListAllTables() const override;
	std::vector<TableDescription> ListAllTablesEx() const override;

	NamesListPtr ListAllColumns(const std::string &tablename) const override;
	std::vector<ColumnDescription> ListAllColumnsEx(
		const std::string &tablename) const override;

	NamesListPtr ListPrimaryKeyColumns(
		const std::string &tablename) const override;

	bool ViewRefersTable(const std::string &tablename,
						 const std::string &viewname) const override;

	NamesListPtr ListAllViewsRefersTable(
		const std::string &tablename) const override;

	std::string GetExactColumnDataType(
		const std::string &columnname) const override;

	ClientUtils::TableAttributeDesc::DType GetColumnDType(
		const std::string &columnname) const override;

	ConstrainedTableAttributeValArrayPtr GetConstrainedPropertyValues(
		const TableAttributeDesc &cp) override;

	FeatureClassDescListPtr ListFeatureClasses() override;
	FeatureClassDetailedDescListPtr ListFeatureClassesDetailed() const override;

	FeatureClassDescPtr GetFeatureClassDesc(const int64_t &id) const;

	int CountFeatures(const FeatureClassDesc &featureClass) const override;

	AssignableFeatureDescListPtr ListAllFeatures(
		const FeatureClassDesc &featureClass) const override;

	TableConstrainedAttributeDescPtr UpdateConstrainedPropertyDesc(
		const TableConstrainedAttributeDesc &cp) const override;

	GeoColumnDescPtr GetGeoColumnDesc(
		const FeatureClassDesc &featureClass) const override;

	FeatureDescPtr GetFeatureDescByGeomId(const long &idgeo) const override;

	FeatureDescPtr GetFeatureDescByLockId(
		const std::string &lockid) const override;

	SimplexPropertyDescListPtr GetSimplexPropertyList(
		const FeatureClassDesc &featureClass) const override;

	ObjectPropertyDescListPtr GetObjectPropertyList(
		const FeatureClassDesc &featureClass,
		bool filterMemberProperties = true) const override;

	ObjectPropertyDescListBySubFeatureKind
	GetObjectPropertyListBySubfeatureKind(
		const FeatureClassDesc &featureClass) const override;

	SimplexPropertyDescListBySubFeatureKind
	GetSimplexPropertyListBySubfeatureKind(
		const FeatureClassDesc &featureClass) const override;

	NamesListPtr ListConstrainedProperties(const FeatureClassDesc &featureClass,
										   bool IsObject) const override;

	VersionedObjectPropertyValueList ListObjectPropertyValueHistory(
		const FeatureDesc &feature) const override;

	VersionedObjectPropertyValueList ListObjectPropertyValueHistory(
		const ObjectPropertyDesc &objProp) const override;

	ConstrainedObjectPropertyDescPtr GetConstrainedObjectProperty(
		const FeatureClassDesc &featureClass,
		const std::string propertyName) const override;

	ConstrainedSimplexPropertyDescPtr GetConstrainedSimplexProperty(
		const FeatureClassDesc &featureClass,
		const std::string propertyName) const override;

	ObjectPropertiesByIdgeoMapPtr GetObjectPropertyValuesOfFeatureClass(
		const FeatureClassDesc &featureClass) const override;

	TableAttributeValListPtr GetObjectPropertyValues(const FeatureDesc &feature,
													 long commitKey
													 = -1) const override;

	void CreateTable(const GST::ClientUtils::TableAttributeDescList &attributes,
					 bool quoteTablename = true) override;

	void DropTable(const std::string &tableName,
				   bool quoteTablename = true) override;

	void InsertRecord(const GST::ClientUtils::TableAttributeValList &attributes,
					  bool quoteTablename = true) override;
	void DeleteRecord(const GST::ClientUtils::TableAttributeVal &attribute,
					  bool quoteTablename = true) const override;

	DataTablePtr GetTableValues(const std::string &tablename,
								const TableAttributeDescList &selection
								= TableAttributeDescList(),
								const std::string &filter
								= std::string()) const override;

	void UpdateTableValues(RecordPtr record) override;
	void UpdateTableValuesInternal(RecordPtr record);

	void UpdateObjectPropertyValue(const FeatureDesc &feature,
								   const TableAttributeVal &value) override;

	void UpdateObjectPropertyValue(
		const FeatureDesc &feature,
		const ConstrainedTableAttributeVal &value) override;

	void UpdateObjectPropertyValues(
		const FeatureDesc &feature,
		const TableAttributeValList &values) override;

	FeatureClassDescPtr RenameFeatureClass(
		FeatureClassDetailedDesc &featureClassDesc,
		const std::string &newName) override;
	FeatureClassDescPtr ChownFeatureClass(
		const FeatureClassDesc &featureClassDesc,
		const Owner &newOwner,
		const std::string &newName = std::string()) const override;
	FeatureClassDescPtr CreateFeatureClassSnapshot(
		const FeatureClassDesc &sourceFeatureClass,
		const Owner &owner,
		const std::string &name,
		const std::string &commitMessage) const override;
	std::pair<FeatureClassDescPtr, FeatureDescListPtr>
	CreateFeatureSelectionSnapshot(
		const FeatureDescListPtr &features,
		const Owner &owner,
		const std::string &name,
		const std::string &commitMessage,
		const boost::optional<AreaLimiter> &areaLimiter
		= boost::none) const override;

	void ProtectFeatureClass(
		const FeatureClassDesc &featureClass) const override;
	void DeprotectFeatureClass(
		const FeatureClassDesc &featureClass) const override;

	void CreatePropertyTable(const FeatureClassDesc &featureClass,
							 const GeoColumnDesc &geocolumn) override;

	ObjectPropertyDescPtr AppendObjectProperty(
		const FeatureClassDesc &featureClass,
		const TableAttributeDesc &attribute,
		const std::string &sub_feature_kind = "") override;

	SimplexPropertyDescPtr AppendSimplexProperty(
		const FeatureClassDesc &featureClass,
		const TableAttributeDesc &attribute,
		const std::string &subFeatureKind = "") override;

	ObjectPropertyDescPtr AppendConstrainedObjectProperty(
		const FeatureClassDesc &featureClass,
		const ConstrainedObjectPropertyDesc &attribute,
		const std::string &sub_feature_kind = "") override;

	void AppendConstrainedSimplexProperty(
		const FeatureClassDesc &featureClass,
		const ConstrainedSimplexPropertyDesc &attribute) override;

	void RenameProperty(const FeatureClassDesc &featureClass,
						TableAttributeDescPtr attribute,
						const std::string &newName) const override;

	void DeleteConstrainedProperty(const FeatureClassDesc &featureClass,
								   const std::string propertyName,
								   const bool isObjectProp = true) override;

	void DeleteProperty(const FeatureClassDesc &featureClass,
						const std::string propertyName,
						bool isObjectProp = true) override;

	void DeleteProperty(
		const ObjectPropertyDesc &objectProperty) const override;
	void DeleteProperty(
		const SimplexPropertyDesc &simplexProperty) const override;

	ObjectPropertyDescPtr RemoveConstrainedInformation(
		const ConstrainedObjectPropertyDesc &objectProperty) override;

	ObjectPropertyDescPtr SetConstrainedInformation(
		const ObjectPropertyDesc &objectProperty,
		const ExternalTableIdentifier &externalTableIdentifier,
		const TableAttributeDescList &columns) override;

	void SimplifyFeature(const FeatureDesc &feature) override;

	void DeleteFeature(long id) const override;

	void DeleteFeatureClass(const std::string &featureClassName) override;
	void DeleteFeatureClass(const FeatureClassDesc &featureClass) override;

	CrudeFeaturePtr GetFeature(
		const FeatureDesc &feature,
		const Geometry::IGeometry::RequestFormat &geometryformat,
		Geometry::SRSPtr srs,
		bool lock = false,
		QueryBoxPtr queryBox = QueryBoxPtr(),
		long commitKey = -1) override;
	CrudeFeaturePtr GetFeature(
		const FeatureDesc &feature,
		const Geometry::IGeometry::RequestFormat &geometryformat,
		Geometry::SRSPtr srs,
		const boost::optional<AreaLimiter> &areaLimiter,
		bool lock = false,
		long commitKey = -1) override;

	CrudeFeaturePtr GetFeatureBinary(const FeatureDesc &feature,
									 Geometry::SRSPtr srs,
									 QueryBoxPtr queryBox = QueryBoxPtr(),
									 long commitKey = -1) override;

	FeatureDescPtr UploadNewFeatureFromMemory(
		const Geometry::StreamableGeometry &feature,
		const FeatureClassDesc &target,
		long commitKey = -1,
		bool updateStats = true);

	FeatureDescPtr UploadNewFeature(const Geometry::StreamableGeometry &feature,
									const FeatureClassDesc &target,
									long commitKey = -1,
									bool updateStats = true) override;

	void UpdateFeatureFromMemory(const Geometry::StreamableGeometry &feature,
								 const std::string &lockid,
								 bool keepLock,
								 const FeatureClassDesc &target,
								 long commitKey = -1,
								 bool updateStats = true);

	void UpdateFeature(const Geometry::StreamableGeometry &feature,
					   const std::string &lockid,
					   const FeatureClassDesc &target,
					   long commitKey = -1,
					   bool updateStats = true) override;

	void InstantUpdateFeature(const Geometry::StreamableGeometry &feature,
							  const long &idgeo,
							  const FeatureClassDesc &target,
							  long commitKey = -1,
							  bool updateStats = true) override;

	void UpdateFeatureKeepLock(const Geometry::StreamableGeometry &feature,
							   const std::string &lockid,
							   const FeatureClassDesc &target,
							   long commitKey = -1,
							   bool updateStats = true) override;

	void UpdateFeature_impl(const Geometry::StreamableGeometry &feature,
							const std::string &lockid,
							bool keepLock,
							const FeatureClassDesc &target,
							long commitKey,
							bool updateStats /*= true*/);

	void MoveFeature(const FeatureDesc &feature,
					 const FeatureClassDesc &target,
					 const std::string &targetfeaturename = "") override;

	void UnlockByKey(const std::string &key) override;

	std::string LockGeometry(long idgeo) override;

	LockInfoListPtr GetLockInfo(long idgeo) const override;

	void ExecuteScript(const std::string &script) override;

	std::vector<unsigned char> GetColorsFromIdx(
		const long &idgeo,
		const std::string &property,
		const std::string &vrtxIdxList,
		const ColorMap::Id &colorMapId) const override;
	// For BinaryGeometry
	void WritePropertyColors(const long &idgeo,
							 const std::string &property,
							 const ColorMap::Id &colorMapId,
							 const std::string &filePath,
							 const Geometry::RequestFormats &file_type) const;
	// For PopGeometry
	void GetColorsFromIdx(const long &idgeo,
						  const std::string &property,
						  const ColorMap::Id &colorMapId,
						  const std::string &path,
						  const FeatureDesc &feature,
						  const Geometry::SRSPtr srs,
						  const Geometry::RequestFormats &file_type) const;

	std::string MakeValidTableName(const std::string tableNameStump,
								   const std::string &suffix = std::string(""),
								   bool quoteTableName = true,
								   int randomChars = 3) const override;

	std::string compute_histogram(const long &idgeo,
								  const std::string &property,
								  const std::string &ranges) const override;

	boost::shared_ptr<std::string> GetSimplexPropertiesAsCsv(
		const FeatureDesc &feature,
		long commitKey = -1) const override;

	std::string getSimplexPropertyValueAtXYZ(
		const long &idgeo,
		const double &x,
		const double &y,
		const double &z,
		const std::string &property) const override;

	std::string getLatestGeoJSONHullGeometry(const long &idgeo) const override;

	void deleteLatestGeometryHull(const long &idgeo) const override;

	long calculateConcaveHull(const long &idgeo) const override;

	long uploadLatestHullForGeometry(
		const std::string &file_path,
		const std::string &file_name,
		const Geometry::IFileSerialisable::FileType &file_type,
		const long &idgeo) const override;

	void uploadTextureForGeometry(const std::string &file_name,
								  const long &idgeo,
								  const bool &update = false) const;
	void downloadTextureForGeometry(const std::string &file_path,
									const long &idgeo) const;

	bool hasGeometryHull(const long &idgeo) const override;

	void CreateUser(const User &user,
					const std::string &initialgroupName) override;

	void DropUser(const std::string &name) override;

	void CreateGroup(const Group &group) override;

	void DropGroup(const std::string &name) override;

	UserListPtr GetAllGSTUsers() const override;

	GroupListPtr GetAllGSTGroups() const override;

	UserListPtr GetUsersByGroup(const std::string &groupName) const override;

	GroupListPtr GetGroupsByUser(const std::string &userName) const override;

	GroupListPtr GetGroupsByCurrentUser() const override;

	void AddUserToGroup(const std::string &userName,
						const std::string &groupName) override;

	void DropUserFromGroup(const std::string &userName,
						   const std::string &groupName) override;

	void ChangeUserPassword(const std::string &userName,
							const std::string &newPassword,
							const std::string &oldPassword) const override;
	void ChangeUserPasswordAsAdmin(
		const User &user,
		const std::string &newPassword) const override;

	std::string GetStorageRevision() const override;

	int CheckCompatibility(const std::string &client_version) const override;

	ServerLicenseListPtr CheckStorageLicense() override;

	Geometry::GSTSRSRefPtr InsertSRS(const Geometry::SRS &new_srs,
									 const std::string &label,
									 const std::string &code_type
									 = std::string(),
									 const std::string &code_value
									 = std::string()) override;

	void UpdateSRS(const Geometry::SRSItemVal &new_srs) override;

	void DeleteSRS(const Geometry::GSTSRSRef &srsref) override;

	Geometry::SRSItemDescListPtr ListAllSRS() const override;

	Geometry::SRSItemDescPtr GetSRSDetailByKey(long srsKey) const override;

	Geometry::SRSItemValPtr GetSRSDefinition(long srsKey) const override;

	void SetSRSForFeatureClass(const Geometry::GSTSRSRef &new_srs,
							   const FeatureClassDesc &fclass) override;

	void UnsetSRSForFeatureClass(const FeatureClassDesc &fclass) override;

	void ChangeSRSForFeatureClass(const Geometry::GSTSRSRef &new_srs,
								  const FeatureClassDesc &fclass,
								  bool transformExistingFeatures
								  = true) override;

	std::string GetProj4ParamFromSRS(const Geometry::SRS &srs) const override;

	AccessLevelListPtr ListAccessLevels() const override;

	AccessLevelPtr GetAccessLevelById(long accessLevelId) const override;

	ServiceDescriptionPtr CreateService(
		const std::string &name,
		const std::string &url,
		long accessLevelId,
		const std::string &user,
		const std::string &secret) const override;

	ServiceDescriptionPtr GetServiceDescriptionById(
		long serviceId) const override;

	void DropService(long serviceId) const override;

	ServiceDescriptionPtr UpdateService(
		long serviceId,
		const std::string &name,
		const std::string &url,
		long accessLevelId,
		const std::string &user,
		const std::string &secret) const override;

	ServiceDescrionListPtr ListServices() const override;

	ServiceDescrionListPtr ListServicesByAccessLevel(
		long accessLevelId) const override;

	LinkAdjacencyListPtr GetChilds(LinkAdjacency::LinkId parent) const override;

	LinkAdjacencyListPtr GetParentsForFeature(
		LinkAdjacency::LinkId featureId) const override;

	LinkAdjacencyListPtr SortLinkAdjacenciesByObjectPropertyRecursively(
		LinkAdjacency::LinkId parent,
		const std::string &objectPropertyName,
		SortOrder sortOrder = SortOrder::Ascending) const override;

	LinkAdjacencyListPtr SortLinkAdjacenciesByDynamicColorScaleRecursively(
		LinkAdjacency::LinkId parent,
		const DynamicColorScale::ID dyncsId,
		SortOrder sortOrder = SortOrder::Ascending) const override;

	AutoSortCriteria AutoSortLinkAdjacenciesByObjectPropertyRecursively(
		LinkAdjacency::LinkId parent,
		const std::string &objectPropertyName,
		SortOrder sortOrder = SortOrder::Ascending) const override;

	AutoSortCriteria AutoSortLinkAdjacenciesByDynamicColorScaleRecursively(
		LinkAdjacency::LinkId parent,
		const DynamicColorScale::ID dyncsId,
		SortOrder sortOrder = SortOrder::Ascending) const override;

	void RemoveAutoSortLinkAdjacencies(
		LinkAdjacency::LinkId parent) const override;

	AssignableElementListPtr GetElements() const override;

	OwnerListPtr GetOwners() const override;

	OwnerListPtr GetAllOwners() const override;

	MoMaPropertyDescPtr CreateMoMaPropertyDesc(
		const std::string &name,
		TableAttributeDesc::DType dtype,
		Owner::OwnerId owner) const override;
	MoMaPropertyDescPtr CreateMoMaPropertyDesc(
		const MoMaPropertyDescPtr desc) const;

	MoMaPropertyDescPtr GetMoMaPropertyDesc(
		MoMaPropertyDesc::PROPERTYID propertyid) const override;

	MoMaPropertyDescListPtr ListMoMaPropertyDesc() const override;

	void RenameMoMaPropertyDesc(const MoMaPropertyDesc::PROPERTYID propertyid,
								const std::string &newname) const override;

	void ChownMoMaPropertyDesc(const MoMaPropertyDesc::PROPERTYID propertyid,
							   const long &newownerid) const override;

	void DeleteMoMaPropertyDesc(
		const MoMaPropertyDesc::PROPERTYID propertyid) const override;

	MoMaPropertyValuePtr CreateMoMaPropertyValue(
		LinkedElement &element,
		const MoMaPropertyDesc &desc,
		TableAttributeValPtr value) const override;

	void DeleteMoMaPropertyValue(const MoMaPropertyValue &value) const override;

	void SetMoMaPropertyValue(
		MoMaPropertyValue &value,
		const TableAttributeValPtr newvalue) const override;

	MoMaPropertyValueListPtr ListMoMaPropertyValues(
		const LinkedElement &element) const override;

	MoMaPropertyValueListPtr ListMoMaPropertyValues(
		const MoMaPropertyDesc::PROPERTYID propertyid) const override;

	LinkAdjacencyPtr CreateLinkAdjacency(LinkAdjacency::LinkId parent,
										 LinkAdjacency::ReferId refId,
										 LinkAdjacency::TargetType refTarget,
										 Owner::OwnerId owner) const override;

	LinkAdjacencyPtr CreateLinkAdjacency(LinkAdjacency::LinkId parent,
										 LinkAdjacency::ReferId refId,
										 LinkAdjacency::TargetType refTarget,
										 Owner::OwnerId owner,
										 int64_t siblingRank) const override;

	void UpdateLinkAdjacencySiblingRank(LinkAdjacency::LinkId linkId,
										int64_t newSiblingRank) const override;

	void DropLinkAdjacency(LinkAdjacency::LinkId linkId) const override;

	void CreateElement(ElementPtr Element,
					   bool uniqueName = false) const override;

	void RenameElement(ElementPtr Element,
					   bool uniqueName = false) const override;

	void DropElement(Element::ElementId id) const override;

	ElementPtr ChownElement(const Element &element,
							const Owner &newOwner,
							const std::string &newName
							= std::string()) const override;

	ColorScaleListPtr GetColorScales() const override;

	ColorValueListPtr GetColorValues(
		ColorScale::ColorScaleId colorscale) const override;

	ColorValuePtr GetColorValue(LinkAdjacency::LinkId lId,
								ColorScale::ColorScaleId cId) const override;

	ColorScale::ColorScaleId AddColorScale(ColorScalePtr cs) const override;

	ColorValue::ColorValueId AddColorValue(ColorValuePtr cv) const override;

	void DeleteColorScale(ColorScale::ColorScaleId csId) const override;

	void DeleteColorValue(ColorValue::ColorValueId cvId) const override;

	void AssignColorScale(ColorScale::ColorScaleId csID,
						  Element::ElementId eId) const override;

	void AssignColorValue(ColorValue::ColorValueId cvId,
						  LinkAdjacency::LinkId lId) const override;

	void UnAssignColorScale(ColorScale::ColorScaleId csID,
							Element::ElementId eId) const override;

	void UnAssignColorValue(ColorValue::ColorValueId cvId,
							LinkAdjacency::LinkId lId) const override;

	FeatureLinkIdGeometryIdPairListPtr ResolveGeometries(
		LinkAdjacency::LinkId rootElement,
		LinkAdjacency::LinkId csRootElement = ROOT_NODE_LINKID,
		ColorScale::ColorScaleId csRootScale = -1) const override;

	FeatureClassDescPtr ResolveFeatureClassFromGeometryId(
		const long &geometryId) const override;

	CrudeFeaturePtr GetFeatureFromMoMa(
		LinkAdjacency::LinkId flid,
		const Geometry::IGeometry::RequestFormat &geometryformat,
		Geometry::SRSPtr srs,
		LinkAdjacency::LinkId csRootElement = ROOT_NODE_LINKID,
		ColorScale::ColorScaleId csRootScale = -1,
		bool lock = false,
		QueryBoxPtr queryBox = QueryBoxPtr(),
		long commitKey = -1) const override;

	// generate web features json model for current user
	std::string ResetWebModel() const;
	// generate web features json model for supplied user
	//
	// requires admin privileges!
	std::string ResetWebModel(const std::string &user) const;
	QueryBoxPtr GetBboxFromMoma(const MoMaKey &momakey,
								Geometry::SRSPtr targetSrs) const override;

	GSTbox GetFeatureBboxTransformed(const FeatureDesc &fDesc,
									 Geometry::SRSPtr targetSrs) const override;

	GSTbox GetBboxForFeaturesTransformed(std::vector<int64_t> featureIds,
										 Geometry::SRSPtr targetSrs) const;

	void ForceUnlinkGeometry(long geometryId) override;

	void CreateUpdateDynamicColorScale(DynamicColorScalePtr dyncs) override;

	void DropDynamicColorScale(const DynamicColorScale::ID &dyncs_id) override;

	DynamicColorScaleListPtr ListDynamicColorScales() const override;

	DynamicColorScalePtr GetDynamicColorScale(
		const DynamicColorScale::ID &dyncs_id) const override;

	long BeginCommit(const std::string &message) const override;

	int EndCommit(long commitKey) const override;

	CommitListPtr ListCommits() const override;

	CommitListPtr ListCommitsByFeature(long geometryId) override;

	CommitVersionListPtr ShowCommit(Commit::CommitKey key) const override;

	void EditCommitMessage(const Commit::CommitKey key,
						   const std::string &message) const override;

	IntersectionInfoPtr SaveBoreholeImage(
		const BoreHoleImageParameters &boreholeParams,
		const OutputImageParameters &outputImageParams) const override;

	IntersectionInfoPtr SaveSectionImage(
		const SectionImageParameters &sectionParams,
		const OutputImageParameters &outputImageParams) const override;

	IntersectionInfoPtr SaveMapImage(
		const MapImageParameters &mapParams,
		const OutputImageParameters &outputImageParams) const override;

	IntersectionInfoPtr SaveCorrelationPlotImage(
		const CorrelationPlotParameters &params,
		const OutputImageParameters &outputImageParams) const override;

	std::string SaveBoreholeAsShapefileZip(
		const BoreHoleImageParameters &boreholeParams,
		const OutputShapeParameters &outputShapeParams) const override;

	std::string SaveSectionAsShapefileZip(
		const SectionImageParameters &sectionParams,
		const OutputShapeParameters &outputShapeParams) const override;

	std::string SaveMapAsShapefileZip(
		const MapImageParameters &mapParams,
		const OutputShapeParameters &outputShapeParams) const override;

	std::string SaveCorrelationPlotAsShapefileZip(
		const CorrelationPlotParameters &params,
		const OutputShapeParameters &outputShapeParams) const override;

	std::string SaveBoreholeAsJSON(
		const BoreHoleImageParameters &boreholeParams,
		const OutputShapeParameters &outputShapeParams) const;

	std::string SaveMultipleBoreholeAsJSON(
		const std::vector<BoreHoleImageParametersPtr> &boreholeParams,
		const OutputShapeParameters &outputShapeParams) const;

	std::string SaveSectionAsJSON(
		const SectionImageParameters &sectionParams,
		const OutputShapeParameters &outputShapeParams) const;

	std::string SaveMapAsJSON(
		const MapImageParameters &mapParams,
		const OutputShapeParameters &outputShapeParams) const;

	IntersectionInfoPtr SaveBoreholeGridImage(
		const BoreholeGridImageParameters &boreholeParams,
		const OutputImageParameters &outputImageParams) const override;
	IntersectionInfoPtr SaveSectionGridImage(
		const SectionGridImageParameters &sectionParams,
		const OutputImageParameters &outputImageParams) const override;
	IntersectionInfoPtr SaveMapGridImage(
		const MapGridImageParameters &mapParams,
		const OutputImageParameters &outputImageParams) const override;

	ColorMap::Id CreateColorMap(const std::string &name,
								const ColorMapSegmentList &segments,
								const Geometry::IGeometry::Color &nodataColor,
								const std::string &regex,
								long accessLevelId,
								bool nodataTransparentForGrids
								= false) override;

	ColorMap::Id CreateDiscreteColorMap(
		const std::string &name,
		const ColorMapDiscreteValueList &values,
		const Geometry::IGeometry::Color &nodataColor,
		const std::string &regex,
		long accessLevelId,
		bool nodataTransparentForGrids = false) override;

	ColorMap::Id CreateConstrainedColorMap(
		const std::string &name,
		const ConstrainedColorValueDesc &constrainedDesc,
		const Geometry::IGeometry::Color &nodataColor,
		const std::string &regex,
		long accessLevelId,
		bool nodataTransparentForGrids = false) override;

	void UpdateColorMap(const ColorMap::Id &id,
						const std::string &name,
						const ColorMapSegmentList &segments,
						const Geometry::IGeometry::Color &nodataColor,
						const std::string &regex,
						long accessLevelId,
						bool nodataTransparentForGrids = false) override;

	void UpdateDiscreteColorMap(const ColorMap::Id &id,
								const std::string &name,
								const ColorMapDiscreteValueList &values,
								const Geometry::IGeometry::Color &nodataColor,
								const std::string &regex,
								long accessLevelId,
								bool nodataTransparentForGrids
								= false) override;

	void UpdateConstrainedColorMap(
		const ColorMap::Id &id,
		const std::string &name,
		const ConstrainedColorValueDesc &constrainedDesc,
		const Geometry::IGeometry::Color &nodataColor,
		const std::string &regex,
		long accessLevelId,
		bool nodataTransparentForGrids = false) override;

	void DeleteColorMap(const ColorMap::Id &id) override;

	ColorMapDescListPtr ListColorMaps() const override;

	ColorMapPtr GetColorMap(const ColorMap::Id &id) const override;

	// color schemes
	ColorSchemePtr CreateContinuousColorScheme(
		const std::string &name,
		const std::vector<ContinuousColorSchemeValue> &values) const override;
	ColorSchemePtr CreateDiscreteColorScheme(
		const std::string &name,
		const std::vector<Utils::ColorRGB> &values) const override;
	ColorSchemePtr UpdateContinuousColorScheme(
		int64_t id,
		const std::string &name,
		const std::vector<ContinuousColorSchemeValue> &values) const override;
	ColorSchemePtr UpdateDiscreteColorScheme(
		int64_t id,
		const std::string &name,
		const std::vector<Utils::ColorRGB> &values) const override;
	void DeleteColorScheme(int64_t id) const override;
	ColorSchemePtr GetColorScheme(int64_t id) const override;
	ColorSchemeList ListColorSchemes() const override;

	void CreateRtreeIndex(long idgeo) const override;

	bool HasRtreeIndex(long idgeo) const override;

	void DropRtreeIndex(long idgeo) const override;

	PropertyAliasPtr GetObjectPropertyAlias(
		const ObjectPropertyDesc &opDesc) const override;

	PropertyAliasPtr GetSimplexPropertyAlias(
		const SimplexPropertyDesc &spDesc) const override;

	void CreateUpdateObjectPropertyAlias(
		const ObjectPropertyDesc &opDesc,
		const std::map<int, PropertyAliasPtr> &propertyAlias) const override;

	void CreateUpdateSimplexPropertyAlias(
		const SimplexPropertyDesc &spDesc,
		const std::map<int, PropertyAliasPtr> &propertyAlias) const override;

	void DropObjectPropertyAlias(
		const ObjectPropertyDesc &opDesc) const override;

	void DropSimplexPropertyAlias(
		const SimplexPropertyDesc &spDesc) const override;

	void DropConstrainedColumnAlias(long mappedColumnId) const override;

	PropertyAliasMapPtr GetObjectPropertyAliasList(
		const FeatureClassDesc &featureClass) const override;
	PropertyAliasMapBySubFeatureKind GetSubKindObjectPropertyAliasList(
		const FeatureClassDesc &featureClass) const override;
	PropertyAliasMapPtr GetSimplexPropertyAliasList(
		const FeatureClassDesc &featureClass) const override;
	PropertyAliasMapBySubFeatureKind GetSubKindSimplexPropertyAliasList(
		const FeatureClassDesc &featureClass) const override;

	LinkAdjacencyListPtr GetAllLinkAdjacencies() const override;
	LinkAdjacencyListPtr GetAllElementLinkAdjacencies() const override;
	LinkAdjacencyListPtr GetAllFeatureLinkAdjacencies() const override;
	ElementListPtr GetAllElements() const override;
	ElementListPtr GetModelsOfFeature(const FeatureDesc &feature) const;

	int64_t getLatestVersionForGeometry(const int64_t idgeo) const;

	static std::vector<std::tuple<double, double, double>> parseFile(
		const std::string &filepath,
		const Geometry::RequestFormats &format,
		const IfcParserSettingsPtr inIfcSettings = IfcParserSettingsPtr());
	static std::vector<std::tuple<double, double, double>> parseIFC(
		const std::string &filepath,
		IfcParserSettingsPtr settings);
	static std::vector<std::tuple<double, double, double>> parseGocad(
		const std::string &filepath);
	static std::vector<std::tuple<double, double, double>> parseSFS(
		const std::string &filepath);

	static std::string convert_proj_definition(const std::string &srs,
											   const std::string &srs_type,
											   const std::string &out_type);
	static std::string get_projection_bounds(const std::string &srs,
											 const std::string &srs_type);

#ifdef WITH_GST_TESTS
	void test_sproc(const Params &in, Params &out) const override;
#endif // WITH_GST_TESTS

	FeatureClassDescPtr CreateFeatureClass(
		const FeatureClassDetailedDesc &featureClassDesc) override;

	///@name LOD Handling
	//@{
	AssignableFeatureDescListPtr GetLODs(
		const FeatureDesc &feature) const override;
	void AddLOD(const FeatureDesc &parentLevel,
				const FeatureDesc &fineLevel) override;
	void RemoveLOD(const FeatureDesc &parentLevel,
				   const FeatureDesc &fineLevel) override;
	//@}

	// web user handling
	void createWebUser(const std::string &name,
					   const std::string &secret,
					   const std::string &linkedGstUser,
					   long accesslevel,
					   const std::string &allowedActionsJson) const override;
	void updateWebUser(const std::string &oldName,
					   const std::string &newName,
					   const std::string &newPassword,
					   const std::string &newLinkedGstUser,
					   long newAccessLevel,
					   const std::string &allowedActionsJson) const override;
	void dropWebUser(const std::string &) const override;
	WebuserDescListPtr listWebUsers() const override;
	void changeWebUserPassword(const std::string &currentPassword,
							   const std::string &newPassword) const override;

	struct SaveFeautreResult
	{
		std::string lock;
		std::string mainFileName;
		std::vector<std::string> fileNames;
		Geometry::SRSPtr srs;
	};
	SaveFeautreResult SaveFeatureStreamed(
		const std::string &path,
		const FeatureDesc &feature,
		const Geometry::IGeometry::RequestFormat &geometryformat,
		Geometry::SRSPtr srs,
		bool lock = false,
		QueryBoxPtr queryBox = QueryBoxPtr(),
		long commitKey = -1,
		boost::optional<std::vector<int64_t>> simplexPropertySelection
		= std::vector<int64_t>(),
		bool write_original_segy_header = false);
	SaveFeautreResult SaveFeatureStreamed(
		const std::string &path,
		const FeatureDesc &feature,
		const Geometry::IGeometry::RequestFormat &geometryformat,
		Geometry::SRSPtr srs,
		const boost::optional<AreaLimiter> &areaLimiter,
		bool lock = false,
		long commitKey = -1,
		boost::optional<std::vector<int64_t>> simplexPropertySelection
		= std::vector<int64_t>(),
		const WriterOptions &writerOptions = WriterOptions(),
		boost::optional<TilingParameters> tilingParameters = boost::none,
		boost::optional<int64_t> gridSegmentationColormapId = boost::none,
		boost::optional<ShiftParameters> shiftParameters = boost::none,
		boost::optional<MeshSimplificationParameters>
			meshSimplificationParameters
		= boost::none);
	// write multiple features into a single file
	//
	// note: currently only supported for ifc, geopackage and shapefile output
	SaveFeautreResult SaveFeaturesStreamed(
		const std::string &path,
		const FeatureClassDesc &featureClass,
		const std::vector<int64_t> &features,
		const Geometry::IGeometry::RequestFormat &geometryformat,
		Geometry::SRSPtr srs,
		const boost::optional<AreaLimiter> &areaLimiter,
		long commitKey = -1,
		boost::optional<std::vector<int64_t>> simplexPropertySelection
		= std::vector<int64_t>(),
		const std::string &archiveName = std::string(),
		boost::optional<ShiftParameters> shiftParameters = boost::none,
		boost::optional<std::map<long, int64_t>> gridSegmentationMap
		= boost::none,
		const std::string &momaStructureJson = std::string(),
		const WriterOptions &writerOptions = WriterOptions());
	FeatureDataList ListFeatureData(const FeatureClassDesc &featureClass) const;
	FeatureDataList ListFeatureDataOfChildFeatures(
		const FeatureDesc &feature) const;

	static ParsedFeatureHeaderPtrListPtr ParseGeneralFeatureHeader(
		const std::string &filePath,
		Geometry::IFileSerialisable::FileType file_format,
		Geometry::GeometryTypes geometry_type);

	static SEGYInfoPtr ParseSEGYHeader(const std::string &filePath);
	static SEGYInfoPtr ParseSEGYHeaderWithOptions(const SEGYInfoPtr &info);
	static std::string StringifySEGYTraceHeader(SEGYTraceHeaderPtr &t);
	void GetSEGYLine(const long &idgeo,
					 const std::string &property,
					 const ColorMap::Id &colorMapId,
					 const std::string &path,
					 const Geometry::SRSPtr srs,
					 bool ignore_interval) const;
	// Calls the Rust side convert_file function
	//
	// Note: Contrary to the usual API functions, this assumes UTF-8 strings in
	// input and output, since this is only used by the webapi.
	static std::vector<std::string> ConvertFile(
		const std::string &inBasePath,
		const std::string &inMainFileName,
		Geometry::IFileSerialisable::FileType inFileFormat,
		const std::string &inSrs,
		const std::string &outBasePath,
		Geometry::IFileSerialisable::FileType outFileFormat,
		const std::string &outSrs);

	static ColorMapPtr ImportColorMap(const std::string &filePath,
									  ColorMapType scaleType);
	static DynamicColorScalePtr ImportDCS(
		const std::string &filePath,
		DynamicColorScale::DynamicCSType scaleType);
	static void ExportDCS(DynamicColorScalePtr dcs,
						  const std::string &filePath,
						  ColorMapOutputFormat of);
	static void ExportColorMap(ColorMapPtr colormap,
							   const std::string &filePath,
							   ColorMapOutputFormat of);
	// query filter
	QueryFilterSummaryList listQueryFilterSummaries() const override;
	QueryFilter getQueryFilter(int64_t id) const override;
	QueryFilter createQueryFilter(NewQueryFilter queryFilter) const override;
	QueryFilter updateQueryFilter(int64_t id,
								  NewQueryFilter queryFilter) const override;
	void deleteQueryFilter(int64_t id) const override;
	std::vector<long> applySpatialFilter(
		const std::vector<long> &idgeos,
		const AreaLimiter &spatialFilter) const override;

	// profile download
	std::string ProfileDownloadShape(
		const ProfileDownloadParameters &profileDownloadParameters,
		const OutputShapeParameters &outputShapeParameters) override;

	// access rights
	void grantAccessRightOnFeatureClass(const FeatureClassDesc &item,
										const Owner &owner,
										AccessRight accessRight) const override;
	void revokeAccessRightFromFeatureClass(const FeatureClassDesc &item,
										   const Owner &owner) const override;
	std::vector<AssignedAccessRight> listAccessRightsOfFeatureClass(
		const FeatureClassDesc &item) const override;
	void grantAccessRightOnElement(const Element &item,
								   const Owner &owner,
								   AccessRight accessRight) const override;
	void revokeAccessRightFromElement(const Element &item,
									  const Owner &owner) const override;
	std::vector<AssignedAccessRight> listAccessRightsOfElement(
		const Element &item) const override;
	void grantAccessRightOnMoMaProperty(const MoMaPropertyDesc &item,
										const Owner &owner,
										AccessRight accessRight) const override;
	void revokeAccessRightFromMoMaProperty(const MoMaPropertyDesc &item,
										   const Owner &owner) const override;
	std::vector<AssignedAccessRight> listAccessRightsOfMoMaProperty(
		const MoMaPropertyDesc &item) const override;

	// Return list of MoMa parent labels for each feature on the specific
	// level/depth of the MoMa tree
	//
	// level can be positive or negative
	// >0 the n-th level from root (1 is top most parent, 2 one below the top
	// most, etc.)
	// <0 the n-th level upwards from the element (-1 is direct parent, -2 grand
	// parent, etc.)
	std::vector<FeatureMoMaParentLabel> GetFeatureMoMaParentLabelByLevel(
		const std::vector<int64_t> &featureIds,
		int32_t level) const;

	Utils::GSTVersionPtr GetStorageVersion() const override;

	static void CheckLicense(LicenseKind licenseKind,
							 const std::string &licsensePath);
#ifdef WITH_GST_TESTS
	void StartTesting() const;
#endif

	LinkedElementPtr GetLinkedElement(LinkAdjacency::LinkId nodelink_id) const;
	void ExtractGroupAndClassFromFeatureClassName(
		const std::string &featureClassName,
		std::string &groupName,
		std::string &className,
		bool &is_private);

	static void SetupGdal(const std::string &additionalProjDataPath
						  = std::string(),
						  const std::string &additonalGdalDataPath
						  = std::string(),
						  const std::string &storagePath = std::string());

	void write_feature_for_webcache(
		const FeatureDesc &feature,
		const Geometry::SRSPtr srs,
		const std::vector<ColorMap::Id> &colorMapIds,
		const std::string &path,
		const std::vector<Geometry::RequestFormats> &file_types) const;

protected:
	void CreateFeatureClass_Impl(
		const FeatureClassDetailedDesc &featureClassDesc) override;

private:
	class Impl;
	Impl *m_impl;
};
} // namespace ClientUtils
} // namespace GST

#endif /* _GRPCACCESS_H_ */
