// Copyright (C) 2019 Jaslo Ziska

#include "photobox_photo.h"

#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>
#include <fcntl.h>

#include <gphoto2/gphoto2.h>
#include <gphoto2/gphoto2-camera.h>

static Camera *camera;
static GPContext *context;

static void dumperror(GPLogLevel level, const char *domain, const char *str, void *data)
{
        // suppress unused parameter errors (ugly):
        (void) level;
        (void) data;

        fprintf(stderr, "[Error Log] %s: %s\n", domain, str);
}

int pb_ph_init(void)
{
        int ret;


        ret = gp_log_add_func(GP_LOG_ERROR, (GPLogFunc) dumperror, 0);
        if (ret < GP_OK) {
                perror("Failed to add logging function");
                return ret;
        }


        context = gp_context_new();

        ret = gp_camera_new(&camera);
        if (ret != GP_OK)
                goto error;

        ret = gp_camera_init(camera, context);
        if (ret != GP_OK)
                goto error;

        return 0;

        error:
        gp_context_unref(context);
        return ret;
}
void pb_ph_uninit(void)
{
        gp_camera_exit(camera, context);
        gp_context_unref(context);
}

// unused, unmaintained:
/*
int pb_ph_capture(pb_ph_buffer *buf)
{
        int ret;
        CameraFile *file;
        CameraFilePath camera_file_path;

        ret = gp_camera_capture(camera, GP_CAPTURE_IMAGE, &camera_file_path, context);
        if (ret != GP_OK) {
                perror_inf("Failed to capture image");
                return ret;
        }

        ret = gp_file_new(&file);
        if (ret != 0) {
                perror_inf("Failed to create new file");
                return ret;
        }

        ret = gp_camera_file_get(camera, camera_file_path.folder, camera_file_path.name, GP_FILE_TYPE_NORMAL,
        file, context);
        if (ret != 0) {
                perror_inf("Failed to get image");
                return ret;
        }

        ret = gp_camera_file_delete(camera, camera_file_path.folder, camera_file_path.name, context);
        if (ret != 0) {
                perror_inf("Failed to delete image from camera");
                return ret;
        }

        gp_file_get_data_and_size(file, (const char **)&buf->base, &buf->size);
        if (ret != 0) {
                perror_inf("Failed to get data and size");
                return ret;
        }

        return 0;
}
*/

int pb_ph_capture_file(const char *fn)
{
        int ret, fd;
        CameraFile *file;
        CameraFilePath camera_file_path;

        ret = gp_camera_capture(camera, GP_CAPTURE_IMAGE, &camera_file_path, context);
        if (ret != GP_OK)
                return ret;

        fd = open(fn, O_CREAT | O_WRONLY, 0644);
        if (fd == -1) {
                ret = GP_ERROR;
                perror("Failed to open/create file");
                goto error_delete;
        }

        ret = gp_file_new_from_fd(&file, fd);
        if (ret != GP_OK)
                goto error_fd;

        ret = gp_camera_file_get(camera, camera_file_path.folder,
                camera_file_path.name, GP_FILE_TYPE_NORMAL, file, context);

        gp_file_free(file);

        error_fd:
        // close fd? done in gphoto?
        close(fd);

        error_delete:
        ret = gp_camera_file_delete(camera, camera_file_path.folder,
                camera_file_path.name, context);

        return ret;
}
