#include "dcp.h"

#include <libdng.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

bool
find_calibration_by_model(char *conffile, char *model, const char *sensor)
{
        // Check config/%model,%sensor.dcp in the current working directory
        sprintf(conffile, "config/%s,%s.dcp", model, sensor);
        if (access(conffile, F_OK) != -1) {
                printf("Found calibration file at %s\n", conffile);
                return true;
        }

        // Check user overridden /etc/megapixels/config/%model,%sensor.dcp
        sprintf(conffile, "%s/megapixels/config/%s,%s.dcp", "/etc", model, sensor);
        if (access(conffile, F_OK) != -1) {
                printf("Found calibration file at %s\n", conffile);
                return true;
        }

        // Check packaged /usr/share/megapixels/config/%model,%sensor.ini
        sprintf(conffile,
                "%s/megapixels/config/%s,%s.dcp",
                "/usr/share",
                model,
                sensor);
        if (access(conffile, F_OK) != -1) {
                printf("Found calibration file at %s\n", conffile);
                return true;
        }
        printf("No calibration found for %s,%s\n", model, sensor);
        return false;
}

bool
find_calibration(char *conffile, const char *sensor)
{
        char model[512];
        FILE *fp;

        if (access("/proc/device-tree/compatible", F_OK) == -1) {
                return false;
        }
        fp = fopen("/proc/device-tree/compatible", "r");
        char *modelptr = model;
        while (1) {
                int c = fgetc(fp);
                if (c == EOF) {
                        *(modelptr) = '\0';
                        return find_calibration_by_model(conffile, model, sensor);
                }
                *(modelptr++) = (char)c;
                if (c == 0) {
                        bool res =
                                find_calibration_by_model(conffile, model, sensor);
                        if (res) {
                                return true;
                        }
                        modelptr = model;
                }
        }
}
struct MPCameraCalibration
parse_calibration_file(const char *path)
{
        struct MPCameraCalibration result;
        libdng_info temp = { 0 };
        libdng_new(&temp);
        libdng_load_calibration_file(&temp, path);

        memcpy(result.color_matrix_1, temp.color_matrix_1, 9 * sizeof(float));
        memcpy(result.color_matrix_2, temp.color_matrix_2, 9 * sizeof(float));
        memcpy(result.forward_matrix_1, temp.forward_matrix_1, 9 * sizeof(float));
        memcpy(result.forward_matrix_2, temp.forward_matrix_2, 9 * sizeof(float));
        result.tone_curve_length = temp.tone_curve_length;
        memcpy(result.tone_curve,
               temp.tone_curve,
               temp.tone_curve_length * sizeof(float));
        return result;
}
