#ifndef PLATFORM_H_
#define PLATFORM_H_
/*---------------------------------------------------------------------------*/
/* platform.h                                                                */
/* copyright (c) innovaphone 2012                                            */
/*                                                                           */
/*---------------------------------------------------------------------------*/

#include <assert.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <TargetConditionals.h>

extern const char * _BUILD_STRING_;
extern const char * __BUILD_STRING__;
extern const char * _VERSION_STR_;
extern const char * _RELEASE_STATE_;
extern const char * _PRODUCT_NAME_;

#ifdef __cplusplus
extern "C" {
#endif

#undef  BIGENDIAN	/* may be defined on command line already */

#define HAVE_INTTYPES_H
# include <inttypes.h>      /* C99 */
typedef uint8_t byte;
typedef uint16_t word;
typedef short int16;
typedef uint32_t dword;
typedef int32_t int32;
typedef int64_t long64;
typedef uint64_t ulong64;
typedef long intp;
typedef unsigned long uintp;

typedef int IoMuxFd;

#define NAMESPACE
#define NAMESPACE_BEGIN
#define NAMESPACE_END
#define USING_NAMESPACE

#define PLATFORM_NO_PACKET
#define PLATFORM_NO_IPADDR
#define PLATFORM_MALLOC
#define TEST_WATCH(x)
#define TEST_WATCH_CONTENT(x,content)

#define _printf vsprintf
#define _sprintf sprintf
#define _snprintf snprintf
inline char * _ip_strdup(const char * s) {
    if (!s) return 0;
    size_t l = strlen(s) + 1;
    return (char *)memcpy(malloc(l), s, l);
}
#define _strdup(x) _ip_strdup(x)

#ifndef ABS
#define ABS(a) ((a) >= 0 ? (a) : (-(a)))
#endif
#ifndef MIN
#define MIN(a,b) ((a)>(b) ? (b) : (a))
#define MAX(a,b) ((a)>(b) ? (a) : (b))
#endif
#define SWAP(t,a,b) { t c=a; a=b; b=c; }
#define GET_BASE(p,s,m) ((s *)((char *)p - (char *)&((s *)0)->m))
#define GET_OFS(s,m) ((int)((char *)(&((s *)0)->m) - (char *)0))

#define READ_WORD_NET(a) ( (((byte *)(a))[0]<<8) + ((byte *)(a))[1] )
#define READ_DWORD_NET(a) ((dword)( (((byte *)(a))[0]<<24) + (((byte *)(a))[1]<<16) + (((byte *)(a))[2]<<8) + ((byte *)(a))[3] ))
#define READ_QUAD_NET(_a) (((ulong64)READ_DWORD_NET(((dword *)(_a))) << 32) + READ_DWORD_NET(((((dword *)(_a)) + 1))))

#define WRITE_WORD_NET(a,w) { word wx=(w); ((byte *)(a))[0]=(wx>>8); ((byte *)(a))[1]=(wx&0xff); }
#define WRITE_DWORD_NET(a,w) { dword wx=(w); ((byte *)(a))[0]=(byte)((wx>>24)); ((byte *)(a))[1]=(byte)((wx>>16)&0xff); ((byte *)(a))[2]=(byte)((wx>>8)&0xff); ((byte *)(a))[3]=(byte)((wx)&0xff); }
#define WRITE_QUAD_NET(a,w) { ulong64 wx=(w); ((byte *)(a))[0]=(byte)((wx>>56)); ((byte *)(a))[1]=(byte)((wx>>48)&0xff); ((byte *)(a))[2]=(byte)((wx>>40)&0xff); ((byte *)(a))[3]=(byte)((wx>>32)&0xff); ((byte *)(a))[4]=(byte)((wx>>24)&0xff); ((byte *)(a))[5]=(byte)((wx>>16)&0xff); ((byte *)(a))[6]=(byte)((wx>>8)&0xff); ((byte *)(a))[7]=(byte)((wx)&0xff); }

#define READ_DWORD_LE(a) ( (((byte *)(a))[0]) + (((byte *)(a))[1]<<8) + (((byte *)(a))[2]<<16) + (((byte *)(a))[3]<<24) )
#define READ_24BIT_LE(a) ( (((byte *)(a))[0]) + (((byte *)(a))[1]<<8) + (((byte *)(a))[2]<<16) )
#define READ_WORD_LE(a) ( (((byte *)(a))[0]) + (((byte *)(a))[1]<<8) )
#define WRITE_WORD_LE(a,w) { word wx=(w); ((byte *)(a))[0]=(wx&0xff); ((byte *)(a))[1]=(wx>>8);  }
#define WRITE_24BIT_LE(a,w) { dword wx=(w); ((byte *)(a))[0]=(byte)((wx)&0xff); ((byte *)(a))[1]=(byte)((wx>>8)&0xff); ((byte *)(a))[2]=(byte)((wx>>16));}
#define WRITE_DWORD_LE(a,w) { dword wx=(w); ((byte *)(a))[0]=(byte)((wx)&0xff); ((byte *)(a))[1]=(byte)((wx>>8)&0xff); ((byte *)(a))[2]=(byte)((wx>>16)&0xff); ((byte *)(a))[3]=(byte)((wx>>24));}
#define WRITE_QUAD_LE(a,w)  { ulong64 wx=(w); ((byte *)(a))[0]=(byte)((wx)&0xff); ((byte *)(a))[1]=(byte)((wx>>8)&0xff); ((byte *)(a))[2]=(byte)((wx>>16)&0xff); ((byte *)(a))[3]=(byte)((wx>>24)&0xff); ((byte *)(a))[4]=(byte)((wx>>32)&0xff); ((byte *)(a))[5]=(byte)((wx>>40)&0xff); ((byte *)(a))[6]=(byte)((wx>>48)&0xff); ((byte *)(a))[7]=(byte)((wx>>56));}

#define _CONCAT_(x,y) x ## y
#define CONCAT(x,y) _CONCAT_(x,y)
#define ANONYMOUS CONCAT(_anonymous, __LINE__)

#define ENGINE_cleanup()
#define DEFAULT_OPUS_COMPLEXITY 5
extern Dl_info dlinfo_;
#define BUILTIN_CALLER ((byte *)(((byte *)(__builtin_return_address(0))) - ((byte *)(dlinfo_.dli_fbase))))

#define PHONE_IOS_LOG_APP_NAME  "myApps"
#define PHONE_IOS_BUNDLE_ID     "com.innovaphone.myapps"
#define PHONE_IOS_APP_GROUP_ID  "group." PHONE_IOS_BUNDLE_ID
#define PHONE_IOS_WINDOW_TITLE  "innovaphone myApps"
#define innovaphoneMyapps       PHONE_IOS_WINDOW_TITLE

#ifdef __cplusplus
}
#endif
/*---------------------------------------------------------------------------*/
#if defined(__cplusplus)

#include <list>
#include <deque>
#include <queue>
#include <map>
#include <string>

#define ASSERT(a, s) { if (!(a)) { if(debug) { debug->printf("ASSERT: %s (%s:%u)", s, __FUNCTION__, __LINE__); } assert(0); } }

#define TLS_DEFAULT_CERTIFICATE_PATH    "/home/root/ssl_cert/server.pem"

#include "common/ilib/btree.h"
#include "common/ilib/ilist.h"
#include "common/ilib/ipaddr.h"
#include "common/ilib/types.h"
#include "common/ilib/lib.h"
#include "common/ilib/httpfile_api.h"
#include "common/os/debug.h"

NAMESPACE_BEGIN
#define ERR(_args_) NAMESPACE::debug->printf _args_
NAMESPACE_END

extern volatile bool connectivity_lan;
// platform_random is a platform dependend random generator and is implemented e.g. in os.cpp/iomux.cpp
extern "C" dword platform_random();

#endif /* defined(__cplusplus) */
/*---------------------------------------------------------------------------*/
#endif /* PLATFORM_H_ */
