#include <_ansi.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/times.h>
#include <sys/mman.h>
#include <hal_user.h>
#include "syscalls.h"
#include <unistd.h>

#include <syscalls_numbers.h>

void _exit(int status)
{
    hal_user_syscall( SYS_EXIT,
                      (int)status, 0, 0, 0 );
}

int _close(int fildes)
{
    return hal_user_syscall( SYS_CLOSE,
                             (int)fildes, 0, 0, 0 );
}
//extern char **environ;
int _execve(const char *path, char *const argv[], char *const envp[])
{
    return hal_user_syscall( SYS_EXEC,
                             (int)path,
                             (int)argv,
                             (int)envp, 0 );
}
pid_t _fork(void)
{
    return hal_user_syscall( SYS_FORK, 0, 0, 0, 0 );
}
int _fstat(int fildes, struct stat *buf){
  errno = ENOSYS;
  return -1;
}
pid_t _getpid(void)
{
    return hal_user_syscall( SYS_GETPID, 0, 0, 0, 0 );
}
int _gettimeofday(struct timeval *ptimeval, void *ptimezone){
    return hal_user_syscall( SYS_TIMEOFDAY,
                            (int) ptimeval,
                            (int) ptimezone, 0, 0);
}


int _isatty(int fildes){
  return hal_user_syscall( SYS_ISATTY,
                           (int)fildes, 0, 0, 0 );
}
int _kill(pid_t pid, int sig)
{
    return hal_user_syscall( SYS_KILL,
                             (int)pid,
                             (int)sig, 0, 0 );
}
int _link(const char *path1, const char *path2){
  errno = ENOSYS;
  return -1;
}

off_t _lseek(int fildes, off_t offset, int whence)
{
    return hal_user_syscall( SYS_LSEEK,
                             (int)fildes,
                             (int)offset,
                             (int)whence, 0 );
}


/////////////////////////////////
int munmap( void         * addr,
            unsigned int   size )
{
    return hal_user_syscall( SYS_MUNMAP,
                             (int)addr,
                             (int)size, 0, 0 );
}

///////////////////////////////
void * mmap( void       * addr,
             unsigned int length,
             int          prot,
             int          flags,
             int          fd,
             unsigned int offset )
{
/*    struct {
      void         * addr;
      unsigned int   length;
      unsigned int   prot; 
      unsigned int   flags;
      unsigned int   fdid; 
      unsigned int   offset;
    }*/
    mmap_attr_t attr;

    attr.addr   = addr;
    attr.length = length;
    attr.prot   = prot;
    attr.flags  = flags;
    attr.fdid   = fd;
    attr.offset = offset;
    if( hal_user_syscall( SYS_MMAP,
                          (int)&attr, 0, 0, 0 ) ) return NULL;
    else                                            return attr.addr;
}

int _open(const char *path, int oflag, ...); // ... ?

int pipe(int fildes[2]){
    return -1;                                                            //return hal_user_syscall( SYS_PIPE, (reg_t)fd, 0, 0, 0 );
}

ssize_t _read(int fildes, void *buf, size_t nbyte)
{
    return hal_user_syscall( SYS_READ,
                             (int)fildes,
                             (int)buf,
                             (int)nbyte, 0 );
}
int _stat(const char * restrict path, struct stat * restrict buf) // vfs_stat a écrire
{
    return hal_user_syscall( SYS_STAT,
                             (int)path,
                             (int)buf, 0, 0 );
}
clock_t _times(struct tms *buffer){ // Manquant
  errno = ENOSYS;
  return -1;
}

int _unlink(const char *path) // vfs_unlink a écrire
{
    return hal_user_syscall( SYS_UNLINK,
                             (int)path, 0, 0, 0 );
}
pid_t _wait(int *stat_loc)
{
    return hal_user_syscall( SYS_WAIT,
                             (int)stat_loc, 0, 0, 0 );
}
ssize_t _write(int fildes, const void *buf, size_t nbyte)
{
    return hal_user_syscall( SYS_WRITE,
                             (int)fildes,
                             (int)buf,
                             (int)nbyte, 0 );
}




/////////////////////////////
char * getcwd( char       * __buf,
            size_t __size )
{
    return (char *) hal_user_syscall( SYS_GETCWD,
                             (int)__buf,
                             (int)__size, 0, 0 );
}
////////////////////////////
int rmdir(const char *__path)
{
    return hal_user_syscall( SYS_RMDIR,
                             (int)__path, 0, 0, 0 );
} 


