/*******************************************************************************
* Copyright 2003-2020 Intel Corporation.
*
* This software and the related documents are Intel copyrighted  materials,  and
* your use of  them is  governed by the  express license  under which  they were
* provided to you (License).  Unless the License provides otherwise, you may not
* use, modify, copy, publish, distribute,  disclose or transmit this software or
* the related documents without Intel's prior written permission.
*
* This software and the related documents  are provided as  is,  with no express
* or implied  warranties,  other  than those  that are  expressly stated  in the
* License.
*******************************************************************************/

#ifndef VM_BASE_H
#define VM_BASE_H

#ifdef __cplusplus
extern "C" {
#endif

/*
// Base definitions
*/
#if defined _WIN32
    #include <windows.h>
    #include <winbase.h>
    #if !defined(_WIN32_WINNT)
        #define _WIN32_WINNT 0x0501
    #endif
#else
    #include <stdlib.h>
    #include <errno.h>
    #include <sys/types.h>
#endif

#include <assert.h>

typedef enum e_vm_Status
{
    VM_OPERATION_FAILED             =-999,
    VM_NOT_INITIALIZED              =-998,
    VM_NOT_ENOUGH_DATA              =-996,  /* not enough input data */
    VM_NULL_PTR                     =-995,
    VM_IMPLICIT_DESTRUCTION         =-994,  /* Impicit object destruction is not allowed*/

    VM_SO_CANT_LOAD                 =-894,
    VM_SO_INVALID_HANDLE            =-893,
    VM_SO_CANT_GET_ADDR             =-892,

    VM_OK                           = 0,    /* no error */

    VM_FILE_ALREADY_EXISTS          = 10,
    VM_TIMEOUT                      = 20

} vm_status;

#if defined (__clang__)
#ifndef _UINT64_T
#define _UINT64_T
#endif
#endif

/*
// Memory operations
*/
void* vm_malloc(size_t iSize, size_t iAlign);
void  vm_free(void* pBuffer);
void* vm_memcpy(void* pDst, const void* pSrc, size_t size);

/*
// Strings operations
*/
#if defined _WIN32
#if !defined(__MIC__)
#include <tchar.h>
#endif

#define vm_main _tmain

#define VM_STRING(x) __T(x)

#if !defined(__MIC__)
typedef TCHAR vm_char;
#else
typedef char vm_char;
#endif

#define vm_string_printf    _tprintf
#define vm_string_fprintf   vm_file_fprintf
#define vm_string_vprintf   _vtprintf
#define vm_string_vfprintf  vm_file_vfprintf

#define vm_string_strcat    _tcscat
#define vm_string_strncat   _tcsncat
#define vm_string_strcspn   _tcscspn
#define vm_string_strspn    _tcsspn

#define vm_string_strcmp    _tcscmp
#define vm_string_strncmp   _tcsnccmp
#define vm_string_stricmp   _tcsicmp
#define vm_string_strnicmp  _tcsncicmp
#define vm_string_strrchr   _tcsrchr
#if defined _UNICODE
#define vm_string_tolower   towlower
#else
#define vm_string_tolower   tolower
#endif

#define vm_string_isdigit   _istdigit
#define vm_string_atoi      _ttoi
#define vm_string_atol      _ttol
#define vm_string_atoll     _ttoi64
#define vm_string_atof      _tstof
#define vm_string_strstr    _tcsstr
#define vm_string_sscanf    _stscanf
#define vm_string_strchr    _tcschr
#define vm_string_strtok    _tcstok
#define vm_string_makepath  _tmakepath

#define vm_findptr intptr_t
#define vm_finddata_t struct _tfinddata_t
#define vm_string_splitpath _tsplitpath
#define vm_string_findclose _findclose
#else
#include <dirent.h>

#if defined _UNICODE
#include <wchar.h>

#define vm_main wmain

#define VM_STRING(x) Lx

#else
#include <string.h>
#include <ctype.h>
#include <stdarg.h>

#define vm_main main

#define VM_STRING(x) x

typedef char vm_char;

#define vm_string_printf    printf
#define vm_string_fprintf   vm_file_fprintf
#define vm_string_vprintf   vprintf
#define vm_string_vfprintf  vm_file_vfprintf

#define vm_string_strcat    strcat
#define vm_string_strncat   strncat
#define vm_string_strcspn   strcspn
#define vm_string_strspn    strspn

#define vm_string_strcmp    strcmp
#define vm_string_strncmp   strncmp
#define vm_string_stricmp   strcasecmp
#define vm_string_strnicmp  strncasecmp
#define vm_string_strrchr   strrchr
#define vm_string_tolower   tolower

#define vm_string_isdigit   isdigit
#define vm_string_atoi      atoi
#define vm_string_atol      atol
#define vm_string_atoll     atoll
#define vm_string_atof      atof

#define vm_string_strstr    strstr
#define vm_string_sscanf    sscanf
#define vm_string_strchr    strchr

#define vm_finddata_t struct _finddata_t
#define vm_string_splitpath _splitpath
#endif
#endif
vm_char* vm_string_strncpy(vm_char *destination, const vm_char *source, size_t num);
int      vm_string_snprintf(vm_char *buffer, size_t n, const vm_char *format, ...);
int      vm_string_vsnprintf(vm_char *buffer, size_t n, const vm_char *format, va_list arg);
size_t   vm_string_strlen(const vm_char *str, size_t bufLen);

/*
// Files operations
*/
#if defined _WIN32
#include <stdio.h>
#if !defined(__MIC__)
#include <io.h>
#endif

#define vm_file_fclose      fclose
#define vm_file_feof        feof
#define vm_file_remove      _tremove
#define vm_file_fflush      fflush

/* binary file IO */
#define vm_file_fread       fread
#define vm_file_fwrite      fwrite

/* character (string) file IO */
#define vm_file_fgets       _fgetts
#define vm_file_fputs       _fputts
#define vm_file_fscanf      _ftscanf
#define vm_file_fprintf     _ftprintf
#define vm_file_vfprintf    _vftprintf

/* temporary file support */
#define vm_file_tmpfile     tmpfile
#define vm_file_tmpnam      tmpnam
#define vm_file_tmpnam_r    tmpnam
#define vm_file_tempnam     tempnam

#define vm_file_fseek       _fseeki64
#define vm_file_ftell       _ftelli64

#define vm_file_access      _taccess
#else
#include <stdio.h>
#include <unistd.h>

#ifndef __USE_LARGEFILE64
#define __USE_LARGEFILE64
#endif

#ifndef __USE_LARGEFILE
#define __USE_LARGEFILE
#endif

#define vm_file_fclose      fclose
#define vm_file_feof        feof
#define vm_file_remove      remove
#define vm_file_fflush      fflush

/* binary file IO */
#define vm_file_fread       fread
#define vm_file_fwrite      fwrite

/* character (string) file IO */
#define vm_file_fgets       fgets
#define vm_file_fputs       fputs
#define vm_file_fscanf      fscanf
#define vm_file_fprintf     fprintf
#define vm_file_vfprintf    vfprintf

/* temporary file support */
#define vm_file_tmpfile     tmpfile
#define vm_file_tmpnam      tmpnam
#define vm_file_tmpnam_r    tmpnam_r
#define vm_file_tempnam     tempnam

unsigned long long vm_file_fseek(FILE *fd, long long position, int mode);
unsigned long long vm_file_ftell(FILE *fd);

#define vm_file_access  access
#endif
FILE* vm_file_fopen(const vm_char* filename, const vm_char* mode);

/* directories operations */
vm_status vm_file_mkdir(const char *path);

/*
// Sysinfo operations
*/
unsigned int vm_sys_info_get_cpu_speed(void);
unsigned int vm_sys_info_get_avail_cpu_num(void);

/*
// Time operations
*/
typedef long long vm_tick;

/* yield the execution of current thread for msec milliseconds */
void vm_time_sleep(unsigned int msec);

/* obtain the clock tick of an uninterrupted master clock */
vm_tick vm_time_get_tick(void);

/* obtain the clock resolution */
vm_tick vm_time_get_frequency(void);


#ifdef __cplusplus
}
#endif

#endif
