#ifndef ESPWEBDAV_H
#define ESPWEBDAV_H

#include <WiFi.h>
#include <SdFat.h>
#include "mbedtls/sha1.h"
// debugging
 #define DBG_PRINT(...) 		{ Serial.print(__VA_ARGS__); }
 #define DBG_PRINTLN(...) 	{ Serial.println(__VA_ARGS__); }
// production
//#define DBG_PRINT(...) 		{ }
//#define DBG_PRINTLN(...) 	{ }

// constants for WebServer
#define CONTENT_LENGTH_UNKNOWN ((size_t) -1)
#define CONTENT_LENGTH_NOT_SET ((size_t) -2)
#define HTTP_MAX_POST_WAIT 		5000 

enum ResourceType { RESOURCE_NONE, RESOURCE_FILE, RESOURCE_DIR };
enum DepthType { DEPTH_NONE, DEPTH_CHILD, DEPTH_ALL };
void sha1( String str_data, uint8_t hash[20] );
//using namespace sdfat;

class ESPWebDAV	{
public:
	bool init(int serverPort);
	bool initSD(int chipSelectPin, SPISettings spiSettings);
	bool isClientWaiting();
	void handleClient(String blank = "");
	void rejectClient(String rejectMessage);
	void sdChdir(const char* path) ;

protected:
	typedef void (ESPWebDAV::*THandlerFunction)(String);
	
	void processClient(THandlerFunction handler, String message);
	void handleNotFound();
	void handleReject(String rejectMessage);
	void handleRequest(String blank);
	void handleOptions(ResourceType resource);
	void handleLock(ResourceType resource);
	void handleUnlock(ResourceType resource);
	void handlePropPatch(ResourceType resource);
	void handleProp(ResourceType resource);
#ifdef GOTEK_SDFAT2
	void sendPropResponse(boolean recursing, FsFile *curFile);
	void handleWriteError(String message, FsFile *wFile);
#else
	void sendPropResponse(boolean recursing, FatFile *curFile);
	void handleWriteError(String message, FatFile *wFile);
#endif 
	void handleGet(ResourceType resource, bool isGet);
	void handlePut(ResourceType resource);

	void handleDirectoryCreate(ResourceType resource);
	void handleMove(ResourceType resource);
	void handleDelete(ResourceType resource);

	// Sections are copied from ESP8266Webserver
	String getMimeType(String path);
	String urlDecode(const String& text);
	String urlToUri(String url);
	bool parseRequest();
	void sendHeader(const String& name, const String& value, bool first = false);
	void send(String code, const char* content_type, const String& content);
	void _prepareHeader(String& response, String code, const char* content_type, size_t contentLength);
	void sendContent(const String& content);
	void sendContent_P(PGM_P content);
	void setContentLength(size_t len);
	size_t readBytesWithTimeout(uint8_t *buf, size_t bufSize);
	size_t readBytesWithTimeout(uint8_t *buf, size_t bufSize, size_t numToRead);
	
	
	// variables pertaining to current most HTTP request being serviced
	WiFiServer *server;
	SdFat sd;

	WiFiClient 	client;
	String 		method;
	String 		uri;
	String 		contentLengthHeader;
	String 		depthHeader;
	String 		hostHeader;
	String		destinationHeader;

	String 		_responseHeaders;
	bool		_chunked;
	int			_contentLength;

	// SD stuff
	//bool isSDInit = false;
};

#endif // ESPWEBDAV_H