#include <unistd.h>
#include "ioall.h"
#include "libqubes-rpc-filecopy.h"
#include "crc32.h"

notify_progress_t *notify_progress_func = NULL;
void register_notify_progress(notify_progress_t *func)
{
    notify_progress_func = func;
}

int copy_file(int outfd, int infd, long long size, unsigned long *crc32)
{
    char buf[4096];
    long long written = 0;
    int ret;
    int count;
    while (written < size) {
        if (size - written > (int)sizeof(buf))
            count = sizeof buf;
        else
            count = size - written;
        ret = read(infd, buf, count);
        if (!ret)
            return COPY_FILE_READ_EOF;
        if (ret < 0)
            return COPY_FILE_READ_ERROR;
        /* acumulate crc32 if requested */
        if (crc32)
            *crc32 = Crc32_ComputeBuf(*crc32, buf, ret);
        if (!write_all(outfd, buf, ret))
            return COPY_FILE_WRITE_ERROR;
        if (notify_progress_func != NULL)
            notify_progress_func(ret, 0);
        written += ret;
    }
    return COPY_FILE_OK;
}

const char * copy_file_status_to_str(int status)
{
    switch (status) {
        case COPY_FILE_OK: return "OK";
        case COPY_FILE_READ_EOF: return "Unexpected end of data while reading";
        case COPY_FILE_READ_ERROR: return "Error reading";
        case COPY_FILE_WRITE_ERROR: return "Error writing";
        default: return "????????";
    }
} 
