#ifndef _SHCSDK_H
#define _SHCSDK_H

#ifdef WIN32

# if defined(SHCSDK_EXPORTS)
#  define WIN32DLL __declspec(dllexport)
# else
#  define WIN32DLL __declspec(dllimport)
# endif

#ifndef ssize_t
#define ssize_t				SSIZE_T
#endif 

#else

#define WIN32DLL
typedef long long INT64;

#endif


typedef void *HSHSDK;
typedef void *HSHFILELIST;

typedef struct {
	char         *path;
	INT64        size;
	char         *lastModified;
	char		 *lastModified_gmt;
	unsigned int attr;
	char         *source;
} SHFILE_STRUCT, *PSHFILE_STRUCT;

// For SHFILE.attr
enum SHCSDK_FILEATTR {
	SHFILEATTR_FOLDER = 0x00000001,
};

// For write policy
enum SHCSDK_WRITEPOLICY {
	SHWRITEPOLICY_NONE      = 0,
	SHWRITEPOLICY_OVERWRITE,
	SHWRITEPOLICY_APPEND,
};

// For error number
enum SHCSDK_ERRNO {	
	SHCERRNO_NOERROR	   = 0,	
	SHCERRNO_UNDEFINED     = 30000,
	SHCERRNO_INVALIDHDL    = 30001,
	SHCERRNO_INVALIDFLHDL  = 30002,
	SHCERRNO_SERVICE       = 30003,
	SHCERRNO_AUTHORIZATION = 30004,
	SHCERRNO_ISBUSY        = 30005,
	SHCERRNO_EXISTSFILE    = 30006,
	SHCERRNO_NOEXISTSFILE  = 30007,
	SHCERRNO_NOAVAILQUOTA  = 30008,
	SHCERRNO_ALREADYEXIST  = 30009,
	// 아래 세개는 실제 나오는 경우가 없어 질것이다.
	// 하지만, 
	////////////////////////////////////////////////////////////////////
	SHCERRNO_RESP_TIMEOUT  = 30010,		// added by sangkeun.ha 20090727 /*NE_TIMEOUT*/
	SHCERRNO_NE_LOOKUP	   = 30011,		// added by webting 20100119 /* NE_LOOKUP */
	SHCERRNO_NE_CONNECT	   = 30012,		// added by webting 20100119 /* NE_CONNECT */
	////////////////////////////////////////////////////////////////////
	SHCERRNO_TRAGETBIGGER  = 30013,
	SHCERRNO_DNS_TIMEOUT   = 30014,
	SHCERRNO_EXT_OVERFLOW  = 30015,
	SHCERRNO_MAX           = 30016,
};

// Callback function format
#ifdef WIN32 // 윈도우에서 다른 언어(C#) 지원하기 위해서 함수call 방식을 __stdcall 해야함
typedef int (__stdcall *sh_callback)(
#else  // WIN32
typedef int (*sh_callback)(
#endif //WIN32
	void  *param,  // Callback function's param
	INT64 progress // Progress
);

typedef int (*down_stream)(
	void* userval,
	const char* buf,
	size_t len
);

typedef ssize_t (*up_stream)(
	void* userval,
	char* buf,
	size_t len
);

#ifdef __cplusplus
extern "C" {
#endif

// SDK 사용할 인스턴스 생성
WIN32DLL HSHSDK sh_init(
	const char  *url,        // Url
	const char  *authString, // Authentication string
	sh_callback proc,        // Callback function
	void        *param);     // Callback function's Param

// SDK 사용한 인스턴스 해제
WIN32DLL void sh_free(
	HSHSDK hshsdk); // SDK HANDLE

// SDK에서 발생한 오류 번호 
WIN32DLL int sh_get_error_number(
	HSHSDK hshsdk); // SDK handle
// 발생한 오류에 대한 상세한 메세지
WIN32DLL const char* sh_get_error_message(
	HSHSDK hshsdk);	// SDK handle

// 디렉토리 생성
// 존재한 디렉토리 생성시 에러 리턴
WIN32DLL int sh_make_directory(
	HSHSDK     hshsdk,     // SDK handle
	const char *drectory); // Directory Path

// 서버의 파일(디렉토리) 복사
WIN32DLL int sh_copy(
	HSHSDK     hshsdk,     // SDK handle
	const char *srcPath,   // Source file | directory
	const char *dstPath,   // Destination file | directory
	int        overwrite); // 0 : Don't overwrite
                           // 1 : Overwrite
// 서버의 파일(디렉토리) 이동
WIN32DLL int sh_move(
	HSHSDK     hshsdk,     // SDK handle
	const char *srcPath,   // Source file | directory
	const char *dstPath,   // Destination file | directory
	int        overwrite); // 0 : Don't overwrite
                           // 1 : Overwrite
// 서버의 파일(디록토리) 삭제
WIN32DLL int sh_delete(
	HSHSDK     hshsdk, // SDK handle
	const char *path); // File | directory

// 파일 업로드
WIN32DLL int sh_upload(
	HSHSDK     hshsdk,      // SDK handle
	const char *srcPath,    // Source file
	const char *dstPath,    // Destination file
	int        writePolicy, // Write policy flag
	INT64      availQuota,
	const char *extSession); // Avail quota

// 파일 다운로드
WIN32DLL int sh_download(
	HSHSDK     hshsdk,      // SDK handle
	const char *srcPath,    // Source file
	const char *dstPath,    // Destination file
	int        writePolicy, // Write policy flag
	INT64      availQuota,  // Avail quota
	const char *extSession); // Extention query

// 서버의 파일 목록
WIN32DLL HSHFILELIST sh_get_filelist(
	HSHSDK       hshsdk, // SDK handle
	const char   *path,  // Path
	unsigned int depth); // 0 : itself
                         // 1 : 1 depth children
                         // 2 : all children

// sh_get_filelist로 얻어온 파일 목록의 개수
WIN32DLL long sh_get_filelist_count(
	HSHSDK       hshsdk, // SDK handle
	HSHFILELIST  hshfl); // File list handle

// 파일 목록의 핸들
WIN32DLL PSHFILE_STRUCT sh_get_file(
	HSHSDK        hshsdk, // SDK handle
	HSHFILELIST   hshfl,  // File list handle
	long          index); // File index

// sh_get_filelist 얻은 파일 핸들 해제
WIN32DLL void sh_free_filelist(
	HSHSDK       hshsdk, // SDK handle
	HSHFILELIST  hshfl); // File list handle

// 데이터 암호화
WIN32DLL int sh_encrypt(
	const char *text,       // String (< 1000 bytes)
	char       *encrypted); // Encrypted String (1000 bytes)

// 전송 속도 설정
WIN32DLL int sh_set_limit(
    HSHSDK	   hshsdk,		// SDK handle
	int		   nLimit);		// Limit value

// 설정된 전송 속도
WIN32DLL int sh_get_limit(
    HSHSDK	   hshsdk		// SDK handle
	);		// Limit value

// 파일(폴더) 존재 유무
WIN32DLL bool sh_file_exist(
	HSHSDK		hshsdk,		// SDK Handle
	const char	*path);		// file/folder Path

// 파일을 버퍼로 다운로드
WIN32DLL int sh_download_buffer(
	HSHSDK     hshsdk,      // SDK handle
	const char *srcPath,    // Source file
	down_stream proc,		// user defined function
	INT64 beingpos,			// point to read
	void*	   userval		// User-supplied value for callback
	); // Avail quota


// 지정크기 만큼 버퍼로 다운로드
// sh_download_buffer range version for GAMPLE
WIN32DLL int sh_download_buffer_r(
	HSHSDK     hshsdk,      // SDK handle
	const char *srcPath,    // Source file
	down_stream proc,		// user defined function
	INT64 beingpos,			// point to read
	INT64 nbytes,			// amount to read
	void*	   userval		// User-supplied value for callback
	);

// 버퍼로부터 파일 업로드 한다
WIN32DLL int sh_upload_buffer(
	HSHSDK     hshsdk,      // SDK handle
	const char *dstPath,    // Destination file
	int writePolicy,		// Write policy flag
	up_stream proc,			// user defined function
	INT64 nbytes,			// write size
	void* userval			// User-supplied value for callback
	);

// 지정된 위치에서 버퍼로부터 파일 업로드 한다.
WIN32DLL int sh_upload_buffer_r(
	HSHSDK     hshsdk,      // SDK handle
	const char *dstPath,    // Destination file
	int writePolicy,		// Write policy flag
	up_stream proc,			// user defined function
	INT64 beginpos,			// write start position
	INT64 nbytes,			// write size
	void* userval			// User-supplied value for callback
	);

// 현재 파일 내 위치
WIN32DLL INT64 sh_get_filepos(
	HSHSDK		hshsdk		// SDK handle
	);

// 타임 서버에 요청 타임 아웃 설정
WIN32DLL void sh_set_sntp_timeout(
	int second				// Time out (Second)
);

// 타임 서버에 요청 타임 아웃 설정
WIN32DLL void sh_set_sntp_timeout(
	int second				// Time out (Second)
);

// 현재 세션의 세션 ID 설정
WIN32DLL int sh_set_sessionID(
    HSHSDK		hshsdk,		// SDK Handle
    const char  *pszID);

// 현재 세션의 세션 ID 정보
WIN32DLL const char* sh_get_sessionID(
	HSHSDK		hshsdk		// SDK Handle
	);

// 세션의 인증 만료 시간 설정
WIN32DLL int sh_set_auth_expire(
	HSHSDK		hshsdk,		// SDK Handle
	int			ntime		// Expire time
	);

// 세션의 인증 만료 시간 정보
WIN32DLL int sh_get_auth_expire(
	HSHSDK		hshsdk		// SDK Handle
	);

// DNS 성공 후 request 서버로 연결에 대한 타임 아웃 설정
WIN32DLL void sh_set_connect_timeout(
	int			second		// Second
	);

// DNS, request 성공 후 발생하는 응답에 대한 타임 아웃 설정
WIN32DLL void sh_set_response_timeout(
	int			second		// Second
	);

// NEW 2010-03-29
// 특정 시간(tStart) 이후에 업로드된 리스트를 얻어온다.
// 고객의 요청에 의해 해당 인터페이스 추가.
WIN32DLL HSHFILELIST sh_get_filelist_certain_time(
	HSHSDK			hshsdk, // SDK handle
	const char		*path,  // Path
	time_t			tStart, // start time
	unsigned int	depth);	// 0 : itself
							// 1 : 1 depth children
							// 2 : all children

// 소켓 연결 타임 아웃 설정
WIN32DLL void sh_set_C_timeout (
	int			second		// Second
	);

// 전송 관련 callback 함수 등록
WIN32DLL int sh_set_transfer_callback (
	HSHSDK			hshsdk, // SDK handle
	sh_callback proc,        // Callback function
	void        *param     // Callback function's Param
	);

// 지정된 파일의 부모 디렉토리 생성 
WIN32DLL int sh_open (
	HSHSDK			hshsdk, // SDK handle 
	const char		*path  // Path
	);

// 버퍼로부터 파일 업로드(존재 시 파일 끝에 추가됨)
WIN32DLL int sh_send_append (
	HSHSDK			hshsdk, // SDK handle 
	const char *dstPath,    // Destination file
	up_stream proc,			// user defined function
	INT64 nbytes,			// write size
	void* userval			// User-supplied value for callback
	);

// 지정된 위치에서 버퍼로 파일 업로드
WIN32DLL int sh_send_block (
	HSHSDK			hshsdk, // SDK handle 
	const char *dstPath,    // Destination file
	up_stream proc,			// user defined function
	INT64 beingpos,			// write start position
	INT64 nbytes,			// write size
	void* userval			// User-supplied value for callback
	);

#ifdef __cplusplus
}
#endif

#endif
