#ifndef LAB_FILE_FIXTURE_H
#define LAB_FILE_FIXTURE_H
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

struct file_fixture {
    int fd;
    int linked;
    size_t length;
    char path[64];
};

static inline int file_fixture_open(struct file_fixture *file, const char *pattern)
{
    file->fd = -1;
    file->linked = 0;
    long page = sysconf(_SC_PAGESIZE);
    if (page <= 0 || strlen(pattern) >= sizeof(file->path)) {
        errno = EINVAL;
        return -1;
    }
    file->length = (size_t)page;
    memcpy(file->path, pattern, strlen(pattern) + 1);
    file->fd = mkstemp(file->path);
    if (file->fd == -1)
        return -1;
    file->linked = 1;
    if (unlink(file->path) == -1)
        return -1;
    file->linked = 0;
    return ftruncate(file->fd, page);
}

static inline int file_fixture_close(struct file_fixture *file)
{
    int result = 0;
    if (file->fd != -1 && close(file->fd) == -1) {
        perror("temporary file close");
        result = -1;
    }
    if (file->linked && unlink(file->path) == -1) {
        perror("temporary file unlink");
        result = -1;
    }
    return result;
}

static inline int file_byte_write(int fd, char byte)
{
    ssize_t count = pwrite(fd, &byte, 1, 0);
    if (count == 1)
        return 0;
    if (count >= 0)
        errno = EIO;
    return -1;
}
#endif
