/*
 * Copyright (C) Tildeslash Ltd. All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License version 3.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 *
 * You must obey the GNU Affero General Public License in all respects
 * for all of the code used other than OpenSSL.  
 */


#include "Config.h"

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <ctype.h>

#include "Str.h"
#include "system/System.h"
#include "File.h"


/**
 * Implementation of the File Facade for Unix systems. 
 *
 * @see http://www.mmonit.com/
 * @file
 */


/* ----------------------------------------------------------- Definitions */


#define DEFAULT_PERM 0666

#define RETURN_FILETYPE(X) do { \
        switch ((X) & S_IFMT) { \
        case S_IFREG:  return 'r'; \
        case S_IFDIR:  return 'd'; \
        case S_IFCHR:  return 'c'; \
        case S_IFBLK:  return 'b'; \
        case S_IFLNK:  return 'l'; \
        case S_IFIFO:  return 'p'; \
        case S_IFSOCK: return 's'; \
        default:       return '?'; \
} } while (0)

const char SEPARATOR_CHAR = '/';
const char *SEPARATOR = "/";
const char PATH_SEPARATOR_CHAR = ':';
const char *PATH_SEPARATOR = ":";


/* ---------------------------------------------------------------- Public */



int File_open(const char *file, const char *mode) {
        if (file && mode) {
                switch(mode[0]) {
                        case 'r':
                                switch (mode[1]) {
                                        case '+': return open(file, O_RDWR|O_NONBLOCK);
                                        default:  return open(file, O_RDONLY|O_NONBLOCK);
                                }
                        case 'w':  
                                switch (mode[1]) {
                                        case '+': return open(file, O_CREAT|O_RDWR|O_TRUNC|O_NONBLOCK, DEFAULT_PERM);
                                        default:  return open(file, O_CREAT|O_WRONLY|O_TRUNC|O_NONBLOCK, DEFAULT_PERM);
                                }
                        case 'a':  
                                switch (mode[1]) {
                                        case '+': return open(file, O_CREAT|O_RDWR|O_APPEND|O_NONBLOCK, DEFAULT_PERM);
                                        default:  return open(file, O_CREAT|O_WRONLY|O_APPEND|O_NONBLOCK, DEFAULT_PERM);
                                }
                }
        }
        errno = EINVAL;
        return -1;
}


int File_close(int fd) {
        int r;
        do
                r = close(fd);
        while (r == -1 && errno == EINTR);
        return (r == 0);
}


int File_rewind(int fd) {
        return (lseek(fd, 0, SEEK_SET) >=0);
}


time_t File_mtime(const char *file) {
        if (file) {
                struct stat buf;
                if (stat(file, &buf) == 0)
                        return buf.st_mtime;
        }
        return -1;
}


time_t File_ctime(const char *file) {
        if (file) {
                struct stat buf;
                if (stat(file, &buf) == 0)
                        return buf.st_ctime;
        }
        return -1;
}


time_t File_atime(const char *file) {
        if (file) {
                struct stat buf;
                if (stat(file, &buf) == 0)
                        return buf.st_atime;
        }
        return -1;
}


int File_isFile(const char *file) {
        if (file) {
                struct stat buf;
                return (stat(file, &buf) == 0 && S_ISREG(buf.st_mode));
        }
        return false;
}


int File_isDirectory(const char *file) {
        if (file) {
                struct stat buf;
                return (stat(file, &buf) == 0 && S_ISDIR(buf.st_mode));
        }
        return false;
}


int File_exist(const char *file) {
        if (file) {
                struct stat buf;
                return (stat(file, &buf) == 0);
        }
        return false;
}


char File_type(const char *file) {
        if (file) {
                struct stat buf;
                if (stat(file, &buf) == 0)
                        RETURN_FILETYPE(buf.st_mode);
        }
        return '?';
}


off_t File_size(const char *file) {
        if (file) {
                struct stat buf;
                if (stat(file, &buf) < 0)
                        return -1;
                return buf.st_size;
        }
        return -1;
}


int File_chmod(const char *file, mode_t mode) {
        if (file)
                return (chmod(file, mode) == 0);
        errno = EINVAL;
        return false;
}


mode_t File_mod(const char *file) {
        if (file) {
                struct stat buf;
                if (stat(file, &buf) == 0)
                        return buf.st_mode;
        }
        return -1;
}


mode_t File_umask(void) {
        mode_t omask = umask(0);
        umask(omask);
        return omask;        
}


mode_t File_setUmask(mode_t mask) {
        mode_t omask = umask(mask);
        return omask;        
}


int File_isReadable(const char *file) {
        if (file) 
                return (access(file, R_OK) == 0);
        return false;
}


int File_isWritable(const char *file) {
        if (file) 
                return (access(file, W_OK) == 0);
        return false;
}


int File_isExecutable(const char *file) {
        if (file) 
                return (access(file, X_OK) == 0);
        return false;
}


int File_delete(const char *file) {
        if (file)
                return (remove(file) == 0);
        errno = ENOENT;
        return false;
}


int File_rename(const char *file, const char *name) {
        if (file)                
                return (rename(file, name) == 0);
        errno = ENOENT;
        return false;
}


const char *File_basename(const char *path) {
        if ((STR_DEF(path))) {
                char *f = strrchr(path, SEPARATOR_CHAR);
                return (f ? ++f : path);
        }
        return path;
}


char *File_dirname(char *path) {
        if ((STR_DEF(path))) {
                char *d = strrchr(path, SEPARATOR_CHAR);
                if (d) 
                        *(d + 1) = 0; /* Keep last separator */
                else {
                        path[0] = '.'; 
                        path[1] = 0;
                }
        }
        return path;
}


const char *File_extension(const char *path) {
        if (STR_DEF(path)) {
                char *e = strrchr(path, '.');
                return (e ? ++e : NULL);
        }
        return NULL;
}


char *File_removeTrailingSeparator(char *path) {
        if (STR_DEF(path)) {
                char *p;
                for (p = path; *p; p++);
                do 
                        *(p--) = 0;
                while ((p > path) && (isspace(*p) || *p == SEPARATOR_CHAR));
        }
        return path;
}


char *File_getRealPath(const char *path, char *resolved) {
        if (path && resolved)
                return realpath(path, resolved);
        return NULL;
}
