#pragma once
#include <cstdint>
#include <vector>
#include <gromox/mapidefs.h>
#include <gromox/zcore_types.hpp>

enum class zcore_response : uint8_t {
	success = 0x00,
	lack_memory = 0x01,
	pull_error = 0x02,
	dispatch_error = 0x03,
	push_error = 0x04,
};

#define EDEF(t, id) t = (id),
#define EOBSOL(t, id)
#define EUNDEF(id)

enum class zcore_callid : uint8_t {
	#include <gromox/zcore_allcalls.hpp>
};

#undef EDEF
#undef EOBSOL
#undef EUNDEF

struct zcreq {
	using view_t = zcreq;
	zcreq() = default; /* Prevent use of direct-init-list */
	virtual ~zcreq() = default;
	zcore_callid call_id{};
};

struct zcreq_logon_token final : public zcreq {
	using view_t = zcreq_logon_token;
	char *token = nullptr, *rhost = nullptr;
};

struct zcreq_logon final : public zcreq {
	using view_t = zcreq_logon;
	char *username = nullptr, *password = nullptr, *rhost = nullptr;
	uint32_t flags = 0;
};
using zcreq_logon_np = zcreq_logon;

struct zcreq_checksession final : public zcreq {
	using view_t = zcreq_checksession;
	GUID hsession{};
};

struct zcreq_uinfo final : public zcreq {
	using view_t = zcreq_uinfo;
	char *username = nullptr;
};

struct zcreq_unloadobject final : public zcreq {
	using view_t = zcreq_unloadobject;
	GUID hsession{};
	uint32_t hobject = 0;
};

struct zcreq_openentry final : public zcreq {
	using view_t = zcreq_openentry;
	GUID hsession{};
	BINARY entryid{};
	uint32_t flags = 0;
};

struct zcreq_openstoreentry final : public zcreq {
	using view_t = zcreq_openstoreentry;
	GUID hsession{};
	BINARY entryid{};
	uint32_t hobject = 0, flags = 0;
};

struct zcreq_openabentry final : public zcreq {
	using view_t = zcreq_openabentry;
	GUID hsession{};
	BINARY entryid{};
};

struct zcreq_resolvename final : public zcreq {
	using view_t = zcreq_resolvename;
	GUID hsession{};
	TARRAY_SET *pcond_set = nullptr;
};

struct zcreq_getpermissions final : public zcreq {
	using view_t = zcreq_getpermissions;
	GUID hsession{};
	uint32_t hobject = 0;
};

struct zcreq_modifypermissions final : public zcreq {
	using view_t = zcreq_modifypermissions;
	GUID hsession{};
	uint32_t hfolder = 0;
	PERMISSION_SET *pset = nullptr;
};

struct zcreq_modifyrules final : public zcreq {
	using view_t = zcreq_modifyrules;
	GUID hsession{};
	uint32_t hfolder = 0, flags = 0;
	RULE_LIST *plist = nullptr;
};

struct zcreq_getabgal final : public zcreq {
	using view_t = zcreq_getabgal;
	GUID hsession{};
};

struct zcreq_loadstoretable final : public zcreq {
	using view_t = zcreq_loadstoretable;
	GUID hsession{};
};

struct zcreq_openstore final : public zcreq {
	using view_t = zcreq_openstore;
	GUID hsession{};
	BINARY entryid{};
};

struct zcreq_openprofilesec final : public zcreq {
	using view_t = zcreq_openprofilesec;
	GUID hsession{};
	const FLATUID *puid = nullptr;
};

struct zcreq_loadhierarchytable final : public zcreq {
	using view_t = zcreq_loadhierarchytable;
	GUID hsession{};
	uint32_t hfolder = 0, flags = 0;
};

struct zcreq_loadcontenttable final : public zcreq {
	using view_t = zcreq_loadcontenttable;
	GUID hsession{};
	uint32_t hfolder = 0, flags = 0;
};

struct zcreq_loadrecipienttable final : public zcreq {
	using view_t = zcreq_loadrecipienttable;
	GUID hsession{};
	uint32_t hmessage = 0;
};

struct zcreq_loadruletable final : public zcreq {
	using view_t = zcreq_loadruletable;
	GUID hsession{};
	uint32_t hfolder = 0;
};
	
struct zcreq_createmessage final : public zcreq {
	using view_t = zcreq_createmessage;
	GUID hsession{};
	uint32_t hfolder = 0, flags = 0;
};

struct zcreq_deletemessages final : public zcreq {
	using view_t = zcreq_deletemessages;
	GUID hsession{};
	uint32_t hfolder = 0, flags = 0;
	BINARY_ARRAY *pentryids = nullptr;
};

struct zcreq_copymessages final : public zcreq {
	using view_t = zcreq_copymessages;
	GUID hsession{};
	uint32_t hsrcfolder = 0, hdstfolder = 0, flags = 0;
	BINARY_ARRAY *pentryids = nullptr;
};

struct zcreq_setreadflags final : public zcreq {
	using view_t = zcreq_setreadflags;
	GUID hsession{};
	uint32_t hfolder = 0, flags = 0;
	BINARY_ARRAY *pentryids = nullptr;
};

struct zcreq_createfolder final : public zcreq {
	using view_t = zcreq_createfolder;
	GUID hsession{};
	uint32_t hparent_folder = 0, folder_type = 0, flags = 0;
	char *folder_name = nullptr, *folder_comment = nullptr;
};

struct zcreq_deletefolder final : public zcreq {
	using view_t = zcreq_deletefolder;
	GUID hsession{};
	BINARY entryid{};
	uint32_t hparent_folder = 0, flags = 0;
};

struct zcreq_emptyfolder final : public zcreq {
	using view_t = zcreq_emptyfolder;
	GUID hsession{};
	uint32_t hfolder = 0, flags = 0;
};

struct zcreq_copyfolder final : public zcreq {
	using view_t = zcreq_copyfolder;
	GUID hsession{};
	BINARY entryid{};
	uint32_t hsrc_folder = 0, hdst_folder = 0, flags = 0;
	char *new_name = nullptr;
};

struct zcreq_getstoreentryid final : public zcreq {
	using view_t = zcreq_getstoreentryid;
	char *mailbox_dn = nullptr;
};

struct zcreq_entryidfromsourcekey final : public zcreq {
	using view_t = zcreq_entryidfromsourcekey;
	GUID hsession{};
	BINARY folder_key{};
	uint32_t hstore = 0;
	BINARY *pmessage_key = nullptr;
};

struct zcreq_storeadvise final : public zcreq {
	using view_t = zcreq_storeadvise;
	GUID hsession{};
	uint32_t hstore = 0, event_mask = 0;
	BINARY *pentryid = nullptr;
};

struct zcreq_unadvise final : public zcreq {
	using view_t = zcreq_unadvise;
	GUID hsession{};
	uint32_t hstore = 0, sub_id = 0;
};

struct zcreq_notifdequeue final : public zcreq {
	using view_t = zcreq_notifdequeue;
	NOTIF_SINK *psink = nullptr;
	uint32_t timeval = 0;
};

struct zcreq_queryrows_v final : public zcreq {
	GUID hsession{};
	uint32_t htable = 0, start = 0, count = 0;
	RESTRICTION *prestriction = nullptr;
	std::optional<proptag_cspan> pproptags;
};

struct zcreq_queryrows final : public zcreq {
	using view_t = zcreq_queryrows_v;
	GUID hsession{};
	uint32_t htable = 0, start = 0, count = 0;
	RESTRICTION *prestriction = nullptr;
	std::optional<proptag_vector> pproptags;
	operator view_t() const {
		view_t v;
		v.hsession = hsession;
		v.htable = htable;
		v.start = start;
		v.count = count;
		v.prestriction = prestriction;
		if (pproptags.has_value()) {
			auto &x = *pproptags;
			v.pproptags.emplace(x);
		}
		return v;
	}
};

struct zcreq_setcolumns_v final : public zcreq {
	GUID hsession{};
	uint32_t htable = 0, flags = 0;
	proptag_cspan pproptags;
};

struct zcreq_setcolumns final : public zcreq {
	using view_t = zcreq_setcolumns_v;
	GUID hsession{};
	uint32_t htable = 0, flags = 0;
	proptag_vector pproptags;
	operator view_t() const {
		view_t v;
		v.hsession = hsession;
		v.htable = htable;
		v.flags = flags;
		v.pproptags = pproptags;
		return v;
	}
};

struct zcreq_seekrow final : public zcreq {
	using view_t = zcreq_seekrow;
	GUID hsession{};
	uint32_t htable = 0, bookmark = 0;
	int32_t seek_rows = 0;
};

struct zcreq_sorttable final : public zcreq {
	using view_t = zcreq_sorttable;
	GUID hsession{};
	uint32_t htable = 0;
	SORTORDER_SET *psortset = nullptr;
};

struct zcreq_getrowcount final : public zcreq {
	using view_t = zcreq_getrowcount;
	GUID hsession{};
	uint32_t htable = 0;
};

struct zcreq_restricttable final : public zcreq {
	using view_t = zcreq_restricttable;
	GUID hsession{};
	uint32_t htable = 0, flags = 0;
	RESTRICTION *prestriction = nullptr;
};

struct zcreq_findrow final : public zcreq {
	using view_t = zcreq_findrow;
	GUID hsession{};
	uint32_t htable = 0, bookmark = 0, flags = 0;
	RESTRICTION *prestriction = nullptr;
};

struct zcreq_createbookmark final : public zcreq {
	using view_t = zcreq_createbookmark;
	GUID hsession{};
	uint32_t htable = 0;
};

struct zcreq_freebookmark final : public zcreq {
	using view_t = zcreq_freebookmark;
	GUID hsession{};
	uint32_t htable = 0, bookmark = 0;
};

struct zcreq_getreceivefolder final : public zcreq {
	using view_t = zcreq_getreceivefolder;
	GUID hsession{};
	uint32_t hstore = 0;
	char *pstrclass = nullptr;
};

struct zcreq_modifyrecipients final : public zcreq {
	using view_t = zcreq_modifyrecipients;
	GUID hsession{};
	uint32_t hmessage = 0, flags = 0;
	TARRAY_SET *prcpt_list = nullptr;
};

struct zcreq_submitmessage final : public zcreq {
	using view_t = zcreq_submitmessage;
	GUID hsession{};
	uint32_t hmessage = 0;
};

struct zcreq_loadattachmenttable final : public zcreq {
	using view_t = zcreq_loadattachmenttable;
	GUID hsession{};
	uint32_t hmessage = 0;
};

struct zcreq_openattachment final : public zcreq {
	using view_t = zcreq_openattachment;
	GUID hsession{};
	uint32_t hmessage = 0, attach_id = 0;
};

struct zcreq_createattachment final : public zcreq {
	using view_t = zcreq_createattachment;
	GUID hsession{};
	uint32_t hmessage = 0;
};

struct zcreq_deleteattachment final : public zcreq {
	using view_t = zcreq_deleteattachment;
	GUID hsession{};
	uint32_t hmessage = 0, attach_id = 0;
};

struct zcreq_setpropvals final : public zcreq {
	using view_t = zcreq_setpropvals;
	GUID hsession{};
	uint32_t hobject = 0;
	TPROPVAL_ARRAY *ppropvals = nullptr;
};

struct zcreq_getpropvals_v final : public zcreq {
	GUID hsession{};
	uint32_t hobject = 0;
	std::optional<proptag_cspan> pproptags;
};

struct zcreq_getpropvals final : public zcreq {
	using view_t = zcreq_getpropvals_v;
	GUID hsession{};
	uint32_t hobject = 0;
	std::optional<proptag_vector> pproptags;
	operator view_t() const {
		view_t v;
		v.hsession = hsession;
		v.hobject = hobject;
		if (pproptags.has_value()) {
			proptag_cspan cs(*pproptags);
			v.pproptags.emplace(cs);
		}
		return v;
	}
};

struct zcreq_deletepropvals_v final : public zcreq {
	GUID hsession{};
	uint32_t hobject = 0;
	proptag_cspan pproptags;
};

struct zcreq_deletepropvals final : public zcreq {
	using view_t = zcreq_deletepropvals_v;
	GUID hsession{};
	uint32_t hobject = 0;
	proptag_vector pproptags;
	operator view_t() const {
		view_t v;
		v.hsession = hsession;
		v.hobject = hobject;
		v.pproptags = pproptags;
		return v;
	}
};

struct zcreq_setmessagereadflag final : public zcreq {
	using view_t = zcreq_setmessagereadflag;
	GUID hsession{};
	uint32_t hmessage = 0, flags = 0;
};

struct zcreq_openembedded final : public zcreq {
	using view_t = zcreq_openembedded;
	GUID hsession{};
	uint32_t hattachment = 0, flags = 0;
};

struct zcreq_getnamedpropids final : public zcreq {
	using view_t = zcreq_getnamedpropids;
	GUID hsession{};
	uint32_t hstore = 0;
	PROPNAME_ARRAY *ppropnames = nullptr;
};

struct zcreq_getpropnames final : public zcreq {
	using view_t = zcreq_getpropnames;
	GUID hsession{};
	uint32_t hstore = 0;
	PROPID_ARRAY ppropids{};
};

struct zcreq_copyto_v final : public zcreq {
	GUID hsession;
	uint32_t hsrcobject = 0, hdstobject = 0, flags = 0;
	proptag_cspan pexclude_proptags;
};

struct zcreq_copyto final : public zcreq {
	using view_t = zcreq_copyto_v;
	GUID hsession{};
	uint32_t hsrcobject = 0, hdstobject = 0, flags = 0;
	proptag_vector pexclude_proptags;
	operator view_t() const {
		view_t v;
		v.hsession = hsession;
		v.hsrcobject = hsrcobject;
		v.hdstobject = hdstobject;
		v.flags = flags;
		v.pexclude_proptags = pexclude_proptags;
		return v;
	}
};

struct zcreq_savechanges final : public zcreq {
	using view_t = zcreq_savechanges;
	GUID hsession{};
	uint32_t hobject = 0;
};

struct zcreq_hierarchysync final : public zcreq {
	using view_t = zcreq_hierarchysync;
	GUID hsession{};
	uint32_t hfolder = 0;
};

struct zcreq_contentsync final : public zcreq {
	using view_t = zcreq_contentsync;
	GUID hsession{};
	uint32_t hfolder = 0;
};

struct zcreq_configsync final : public zcreq {
	using view_t = zcreq_configsync;
	GUID hsession{};
	uint32_t hctx = 0, flags = 0;
	BINARY *pstate = nullptr;
	RESTRICTION *prestriction = nullptr;
};

struct zcreq_statesync final : public zcreq {
	using view_t = zcreq_statesync;
	GUID hsession{};
	uint32_t hctx = 0;
};

struct zcreq_syncmessagechange final : public zcreq {
	using view_t = zcreq_syncmessagechange;
	GUID hsession{};
	uint32_t hctx = 0;
};

struct zcreq_syncfolderchange final : public zcreq {
	using view_t = zcreq_syncfolderchange;
	GUID hsession{};
	uint32_t hctx = 0;
};

struct zcreq_syncreadstatechanges final : public zcreq {
	using view_t = zcreq_syncreadstatechanges;
	GUID hsession{};
	uint32_t hctx = 0;
};

struct zcreq_syncdeletions final : public zcreq {
	using view_t = zcreq_syncdeletions;
	GUID hsession{};
	uint32_t hctx = 0, flags = 0;
};

struct zcreq_hierarchyimport final : public zcreq {
	using view_t = zcreq_hierarchyimport;
	GUID hsession{};
	uint32_t hfolder = 0;
};

struct zcreq_contentimport final : public zcreq {
	using view_t = zcreq_contentimport;
	GUID hsession{};
	uint32_t hfolder = 0;
};

struct zcreq_configimport final : public zcreq {
	using view_t = zcreq_configimport;
	GUID hsession{};
	uint32_t hctx = 0;
	uint8_t sync_type = 0;
	BINARY *pstate = nullptr;
};
	
struct zcreq_stateimport final : public zcreq {
	using view_t = zcreq_stateimport;
	GUID hsession{};
	uint32_t hctx = 0;
};

struct zcreq_importmessage final : public zcreq {
	using view_t = zcreq_importmessage;
	GUID hsession{};
	uint32_t hctx = 0, flags = 0;
	TPROPVAL_ARRAY *pproplist = nullptr;
};
	
struct zcreq_importfolder final : public zcreq {
	using view_t = zcreq_importfolder;
	GUID hsession{};
	uint32_t hctx = 0;
	TPROPVAL_ARRAY *pproplist = nullptr;
};

struct zcreq_importdeletion final : public zcreq {
	using view_t = zcreq_importdeletion;
	GUID hsession{};
	uint32_t hctx = 0, flags = 0;
	BINARY_ARRAY *pbins = nullptr;
};

struct zcreq_importreadstates final : public zcreq {
	using view_t = zcreq_importreadstates;
	GUID hsession{};
	uint32_t hctx = 0;
	STATE_ARRAY *pstates = nullptr;
};

struct zcreq_getsearchcriteria final : public zcreq {
	using view_t = zcreq_getsearchcriteria;
	GUID hsession{};
	uint32_t hfolder = 0;
};
	
struct zcreq_setsearchcriteria final : public zcreq {
	using view_t = zcreq_setsearchcriteria;
	GUID hsession{};
	uint32_t hfolder = 0, flags = 0;
	BINARY_ARRAY *pfolder_array = nullptr;
	RESTRICTION *prestriction = nullptr;
};

struct zcreq_messagetorfc822 final : public zcreq {
	using view_t = zcreq_messagetorfc822;
	GUID hsession{};
	uint32_t hmessage = 0;
};

struct zcreq_rfc822tomessage final : public zcreq {
	using view_t = zcreq_rfc822tomessage;
	GUID hsession{};
	uint32_t hmessage = 0, mxf_flags = 0;
	BINARY *peml_bin = nullptr;
};

struct zcreq_messagetoical final : public zcreq {
	using view_t = zcreq_messagetoical;
	GUID hsession{};
	uint32_t hmessage = 0;
};

struct zcreq_icaltomessage final : public zcreq {
	using view_t = zcreq_icaltomessage;
	GUID hsession{};
	uint32_t hmessage = 0;
	BINARY *pical_bin = nullptr;
};

enum imtomessage2_type {
	IMTOMESSAGE_ICAL = 0,
	IMTOMESSAGE_VCARD,
};

struct zcreq_imtomessage2 final : public zcreq {
	using view_t = zcreq_imtomessage2;
	GUID session{};
	uint32_t folder = 0, data_type = 0;
	char *im_data = nullptr;
};

struct zcreq_messagetovcf final : public zcreq {
	using view_t = zcreq_messagetovcf;
	GUID hsession{};
	uint32_t hmessage = 0;
};

struct zcreq_vcftomessage final : public zcreq {
	using view_t = zcreq_vcftomessage;
	GUID hsession{};
	uint32_t hmessage = 0;
	BINARY *pvcf_bin = nullptr;
};

struct zcreq_setpasswd final : public zcreq {
	using view_t = zcreq_setpasswd;
	char *username = nullptr, *passwd = nullptr, *new_passwd = nullptr;
};

struct zcreq_linkmessage final : public zcreq {
	using view_t = zcreq_linkmessage;
	GUID hsession{};
	BINARY search_entryid{}, message_entryid{};
};

struct zcreq_savesession final : public zcreq {
	using view_t = zcreq_savesession;
	GUID hsession{};
};

struct zcreq_restoresession final : public zcreq {
	using view_t = zcreq_restoresession;
	BINARY *pdata_bin = nullptr;
};

struct zcreq_essdn_to_username final : public zcreq {
	using view_t = zcreq_essdn_to_username;
	char *essdn = nullptr;
};

struct zcreq_getuserfreebusy final : public zcreq {
	using view_t = zcreq_getuserfreebusy;
	GUID hsession{};
	BINARY entryid{};
	int64_t starttime = 0, endtime = 0;
};

struct zcreq_getuserfreebusyical final : public zcreq {
	using view_t = zcreq_getuserfreebusyical;
	GUID hsession{};
	BINARY entryid{};
	int64_t starttime = 0, endtime = 0;
};

struct zcresp {
	using view_t = zcresp;
	zcresp() = default; /* Prevent use of direct-init-list */
	virtual ~zcresp() = default;
	zcore_callid call_id{};
	ec_error_t result{};
};

struct zcresp_logon final : public zcresp {
	using view_t = zcresp_logon;
	GUID hsession{};
};

struct zcresp_logon_token final : public zcresp {
	using view_t = zcresp_logon_token;
	GUID hsession{};
};

struct zcresp_uinfo final : public zcresp {
	using view_t = zcresp_uinfo;
	BINARY entryid{};
	std::string pdisplay_name, px500dn;
	uint32_t privilege_bits = 0;
};

struct zcresp_openentry final : public zcresp {
	using view_t = zcresp_openentry;
	zs_objtype mapi_type{};
	uint32_t hobject = 0;
};

struct zcresp_openstoreentry final : public zcresp {
	using view_t = zcresp_openstoreentry;
	zs_objtype mapi_type{};
	uint32_t hxobject = 0;
};

struct zcresp_openabentry final : public zcresp {
	using view_t = zcresp_openabentry;
	zs_objtype mapi_type{};
	uint32_t hobject = 0;
};

struct zcresp_resolvename final : public zcresp {
	using view_t = zcresp_resolvename;
	TARRAY_SET result_set{};
};

struct zcresp_getpermissions final : public zcresp {
	using view_t = zcresp_getpermissions;
	PERMISSION_SET perm_set{};
};

struct zcresp_getabgal final : public zcresp {
	using view_t = zcresp_getabgal;
	BINARY entryid{};
};

struct zcresp_loadstoretable final : public zcresp {
	using view_t = zcresp_loadstoretable;
	uint32_t hobject = 0;
};

struct zcresp_openstore final : public zcresp {
	using view_t = zcresp_openstore;
	uint32_t hobject = 0;
};

struct zcresp_openprofilesec final : public zcresp {
	using view_t = zcresp_openprofilesec;
	uint32_t hobject = 0;
};

struct zcresp_loadhierarchytable final : public zcresp {
	using view_t = zcresp_loadhierarchytable;
	uint32_t hobject = 0;
};

struct zcresp_loadcontenttable final : public zcresp {
	using view_t = zcresp_loadcontenttable;
	uint32_t hobject = 0;
};

struct zcresp_loadrecipienttable final : public zcresp {
	using view_t = zcresp_loadrecipienttable;
	uint32_t hobject = 0;
};

struct zcresp_loadruletable final : public zcresp {
	using view_t = zcresp_loadruletable;
	uint32_t hobject = 0;
};
	
struct zcresp_createmessage final : public zcresp {
	using view_t = zcresp_createmessage;
	uint32_t hobject = 0;
};

struct zcresp_createfolder final : public zcresp {
	using view_t = zcresp_createfolder;
	uint32_t hobject = 0;
};

struct zcresp_getstoreentryid final : public zcresp {
	using view_t = zcresp_getstoreentryid;
	BINARY entryid{};
};

struct zcresp_entryidfromsourcekey final : public zcresp {
	using view_t = zcresp_entryidfromsourcekey;
	BINARY entryid{};
};

struct zcresp_storeadvise final : public zcresp {
	using view_t = zcresp_storeadvise;
	uint32_t sub_id = 0;
};

struct zcresp_notifdequeue final : public zcresp {
	using view_t = zcresp_notifdequeue;
	ZNOTIFICATION_ARRAY notifications{};
};

struct zcresp_queryrows final : public zcresp {
	using view_t = zcresp_queryrows;
	TARRAY_SET rowset{};
};

struct zcresp_setcolumns final : public zcresp {
	using view_t = zcresp_setcolumns;
	GUID hsession{};
	uint32_t htable = 0, flags = 0;
	PROPTAG_ARRAY *pproptags = nullptr;
};

struct zcresp_seekrow final : public zcresp {
	using view_t = zcresp_seekrow;
	int32_t sought_rows = 0;
};

struct zcresp_getrowcount final : public zcresp {
	using view_t = zcresp_getrowcount;
	uint32_t count = 0;
};

struct zcresp_findrow final : public zcresp {
	using view_t = zcresp_findrow;
	uint32_t row_idx = 0;
};

struct zcresp_createbookmark final : public zcresp {
	using view_t = zcresp_createbookmark;
	uint32_t bookmark = 0;
};

struct zcresp_getreceivefolder final : public zcresp {
	using view_t = zcresp_getreceivefolder;
	BINARY entryid{};
};

struct zcresp_loadattachmenttable final : public zcresp {
	using view_t = zcresp_loadattachmenttable;
	uint32_t hobject = 0;
};

struct zcresp_openattachment final : public zcresp {
	using view_t = zcresp_openattachment;
	uint32_t hobject = 0;
};

struct zcresp_createattachment final : public zcresp {
	using view_t = zcresp_createattachment;
	uint32_t hobject = 0;
};

struct zcresp_getpropvals final : public zcresp {
	using view_t = zcresp_getpropvals;
	TPROPVAL_ARRAY propvals{};
};

struct zcresp_openembedded final : public zcresp {
	using view_t = zcresp_openembedded;
	uint32_t hobject = 0;
};

struct zcresp_getnamedpropids final : public zcresp {
	using view_t = zcresp_getnamedpropids;
	PROPID_ARRAY propids{};
};

struct zcresp_getpropnames final : public zcresp {
	using view_t = zcresp_getpropnames;
	PROPNAME_ARRAY propnames{};
};

struct zcresp_hierarchysync final : public zcresp {
	using view_t = zcresp_hierarchysync;
	uint32_t hobject = 0;
};

struct zcresp_contentsync final : public zcresp {
	using view_t = zcresp_contentsync;
	uint32_t hobject = 0;
};

struct zcresp_configsync final : public zcresp {
	using view_t = zcresp_configsync;
	uint8_t b_changed = false;
	uint32_t count = 0;
};

struct zcresp_statesync final : public zcresp {
	using view_t = zcresp_statesync;
	BINARY state{};
};

struct zcresp_syncmessagechange final : public zcresp {
	using view_t = zcresp_syncmessagechange;
	uint8_t b_new = false;
	TPROPVAL_ARRAY proplist{};
};

struct zcresp_syncfolderchange final : public zcresp {
	using view_t = zcresp_syncfolderchange;
	TPROPVAL_ARRAY proplist{};
};

struct zcresp_syncreadstatechanges final : public zcresp {
	using view_t = zcresp_syncreadstatechanges;
	STATE_ARRAY states{};
};

struct zcresp_syncdeletions final : public zcresp {
	using view_t = zcresp_syncdeletions;
	BINARY_ARRAY bins{};
};

struct zcresp_hierarchyimport final : public zcresp {
	using view_t = zcresp_hierarchyimport;
	uint32_t hobject = 0;
};

struct zcresp_contentimport final : public zcresp {
	using view_t = zcresp_contentimport;
	uint32_t hobject = 0;
};
	
struct zcresp_stateimport final : public zcresp {
	using view_t = zcresp_stateimport;
	BINARY state{};
};

struct zcresp_importmessage final : public zcresp {
	using view_t = zcresp_importmessage;
	uint32_t hobject = 0;
};

struct zcresp_getsearchcriteria final : public zcresp {
	using view_t = zcresp_getsearchcriteria;
	BINARY_ARRAY folder_array{};
	RESTRICTION *prestriction = nullptr;
	uint32_t search_stat = 0;
};

struct zcresp_messagetorfc822 final : public zcresp {
	using view_t = zcresp_messagetorfc822;
	BINARY eml_bin{};
};

struct zcresp_messagetoical final : public zcresp {
	using view_t = zcresp_messagetoical;
	BINARY ical_bin{};
};

struct zcresp_messagetovcf final : public zcresp {
	using view_t = zcresp_messagetovcf;
	BINARY vcf_bin{};
};

struct zcresp_imtomessage2 final : public zcresp {
	using view_t = zcresp_imtomessage2;
	LONG_ARRAY msg_handles{};
};

struct zcresp_essdn_to_username final : public zcresp {
	using view_t = zcresp_essdn_to_username;
	char *username = nullptr;
};

struct zcresp_getuserfreebusy final : public zcresp {
	using view_t = zcresp_getuserfreebusy;
	std::vector<freebusy_event> fb_events;
};

struct zcresp_getuserfreebusyical final : public zcresp {
	using view_t = zcresp_getuserfreebusyical;
	BINARY ical_bin{};
};

using zcresp_checksession = zcresp;
using zcresp_configimport = zcresp;
using zcresp_copyfolder = zcresp;
using zcresp_copymessages = zcresp;
using zcresp_copyto = zcresp;
using zcresp_deleteattachment = zcresp;
using zcresp_deletefolder = zcresp;
using zcresp_deletemessages = zcresp;
using zcresp_deletepropvals = zcresp;
using zcresp_emptyfolder = zcresp;
using zcresp_freebookmark = zcresp;
using zcresp_icaltomessage = zcresp;
using zcresp_importdeletion = zcresp;
using zcresp_importfolder = zcresp;
using zcresp_importreadstates = zcresp;
using zcresp_linkmessage = zcresp;
using zcresp_modifypermissions = zcresp;
using zcresp_modifyrecipients = zcresp;
using zcresp_modifyrules = zcresp;
using zcresp_restricttable = zcresp;
using zcresp_rfc822tomessage = zcresp;
using zcresp_savechanges = zcresp;
using zcresp_setmessagereadflag = zcresp;
using zcresp_setpasswd = zcresp;
using zcresp_setpropvals = zcresp;
using zcresp_setreadflags = zcresp;
using zcresp_setsearchcriteria = zcresp;
using zcresp_sorttable = zcresp;
using zcresp_submitmessage = zcresp;
using zcresp_unadvise = zcresp;
using zcresp_unloadobject = zcresp;
using zcresp_vcftomessage = zcresp;
using zcresp_logon_np = zcresp_logon;

enum {
	MXF_UNWRAP_SMIME_CLEARSIGNED = 0x1U,
	MXF_ADD_RCVD_TIMESTAMP = 0x2U,
};
