#include <luna/SystemError.h>

const char* error_string(int error)
{
    switch (error)
    {
    case 0: return "Success (not an error)";
    case EPERM: return "Operation not permitted";
    case ENOENT: return "No such file or directory";
    case ESRCH: return "No such process";
    case EINTR: return "Interrupted system call";
    case EIO: return "Input/output error";
    case ENXIO: return "No such device or address";
    case E2BIG: return "Argument list too long";
    case ENOEXEC: return "Exec format error";
    case EBADF: return "Bad file descriptor";
    case ECHILD: return "No child processes";
    case EAGAIN: return "Resource temporarily unavailable";
    case ENOMEM: return "Cannot allocate memory";
    case EACCES: return "Permission denied";
    case EFAULT: return "Bad address";
    case ENOTBLK: return "Block device required";
    case EBUSY: return "Device or resource busy";
    case EEXIST: return "File exists";
    case EXDEV: return "Invalid cross-device link";
    case ENODEV: return "No such device";
    case ENOTDIR: return "Not a directory";
    case EISDIR: return "Is a directory";
    case EINVAL: return "Invalid argument";
    case ENFILE: return "Too many open files in system";
    case EMFILE: return "Too many open files";
    case ENOTTY: return "Inappropriate ioctl for device";
    case ETXTBSY: return "Text file busy";
    case EFBIG: return "File too large";
    case ENOSPC: return "No space left on device";
    case ESPIPE: return "Illegal seek";
    case EROFS: return "Read-only file system";
    case EMLINK: return "Too many links";
    case EPIPE: return "Broken pipe";
    case EDOM: return "Numerical argument out of domain";
    case ERANGE: return "Numerical result out of range";
    case EDEADLK: return "Resource deadlock avoided";
    case ENAMETOOLONG: return "File name too long";
    case ENOLCK: return "No locks available";
    case ENOSYS: return "Function not implemented";
    case ENOTEMPTY: return "Directory not empty";
    case ELOOP: return "Too many levels of symbolic links";
    case ENOMSG: return "No message of desired type";
    case EOVERFLOW: return "Value too large for defined data type";
    case EILSEQ: return "Invalid or incomplete multibyte or wide character";
    case ENOTSOCK: return "Socket operation on non-socket";
    case ENOTSUP: return "Operation not supported";
    case EADDRINUSE: return "Address already in use";
    case ENETRESET: return "Network dropped connection on reset";
    case ECONNRESET: return "Connection reset by peer";
    case EISCONN: return "Transport endpoint is already connected";
    case ETIMEDOUT: return "Connection timed out";
    case EALREADY: return "Operation already in progress";
    case EDESTADDRREQ: return "Destination address required";
    case EPROTOTYPE: return "Protocol wrong type for socket";
    case EAFNOSUPPORT: return "Address family not supported by protocol";
    case ENOTCONN: return "Transport endpoint is not connected";
    case EADDRNOTAVAIL: return "Cannot assign requested address";
    case ECONNREFUSED: return "Connection refused";
    case EINPROGRESS: return "Operation now in progress";
    case ECONNABORTED: return "Software caused connection abort";
    case EHOSTUNREACH: return "No route to host";
    case EMSGSIZE: return "Message too long";
    case ENETDOWN: return "Network is down";
    case ENETUNREACH: return "Network is unreachable";
    case ENOBUFS: return "No buffer space available";
    case ENOPROTOOPT: return "Protocol not available";
    case EPROTONOSUPPORT: return "Protocol not supported";
    default: return "Unknown error";
    }
}

const char* error_name(int error)
{
#define ERROR(name)                                                                                                    \
    case name: return #name

    switch (error)
    {
        ERROR(EPERM);
        ERROR(ENOENT);
        ERROR(ESRCH);
        ERROR(EINTR);
        ERROR(EIO);
        ERROR(ENXIO);
        ERROR(E2BIG);
        ERROR(ENOEXEC);
        ERROR(EBADF);
        ERROR(ECHILD);
        ERROR(EAGAIN);
        ERROR(ENOMEM);
        ERROR(EACCES);
        ERROR(EFAULT);
        ERROR(ENOTBLK);
        ERROR(EBUSY);
        ERROR(EEXIST);
        ERROR(EXDEV);
        ERROR(ENODEV);
        ERROR(ENOTDIR);
        ERROR(EISDIR);
        ERROR(EINVAL);
        ERROR(ENFILE);
        ERROR(EMFILE);
        ERROR(ENOTTY);
        ERROR(ETXTBSY);
        ERROR(EFBIG);
        ERROR(ENOSPC);
        ERROR(ESPIPE);
        ERROR(EROFS);
        ERROR(EMLINK);
        ERROR(EPIPE);
        ERROR(EDOM);
        ERROR(ERANGE);
        ERROR(EDEADLK);
        ERROR(ENAMETOOLONG);
        ERROR(ENOLCK);
        ERROR(ENOSYS);
        ERROR(ENOTEMPTY);
        ERROR(ELOOP);
        ERROR(ENOMSG);
        ERROR(EOVERFLOW);
        ERROR(EILSEQ);
        ERROR(ENOTSOCK);
        ERROR(ENOTSUP);
        ERROR(EADDRINUSE);
        ERROR(ENETRESET);
        ERROR(ECONNRESET);
        ERROR(EISCONN);
        ERROR(ETIMEDOUT);
        ERROR(EALREADY);
        ERROR(EDESTADDRREQ);
        ERROR(EPROTOTYPE);
        ERROR(EAFNOSUPPORT);
        ERROR(ENOTCONN);
        ERROR(EADDRNOTAVAIL);
        ERROR(ECONNREFUSED);
        ERROR(EINPROGRESS);
        ERROR(ECONNABORTED);
        ERROR(EHOSTUNREACH);
        ERROR(EMSGSIZE);
        ERROR(ENETDOWN);
        ERROR(ENETUNREACH);
        ERROR(ENOBUFS);
        ERROR(ENOPROTOOPT);
        ERROR(EPROTONOSUPPORT);
    default: return nullptr;
    }

#undef ERROR
}