#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <node_api.h>
#include "ctrlgenficum.h"

#define DECLARE_NAPI_METHOD(name, func)                                        \
  { name, 0, func, 0, 0, 0, napi_default, 0 }

static napi_value Main(napi_env env, napi_callback_info info) {
    napi_status status;
    size_t argc = 6;
    napi_value args[6];
        
    // Get arguments from JavaScript
    status = napi_get_cb_info(env, info, &argc, args, NULL, NULL);
    assert(status == napi_ok);
    
    if (argc < 6) {
        napi_throw_error(env, NULL, "main requires 6 arguments: ficumin, ficumout, dirtables, log, gestion_portee, finess_geo");
        return NULL;
    }
    
    // Extract arguments
    char ficumin[256] = {0};
    char ficumout[256] = {0};
    char dirtables[256] = {0};
    int log_flag, gestion_portee, finess_geo;
    
    // Extract ficumin string (args[0])
    size_t str_length;
    status = napi_get_value_string_utf8(env, args[0], ficumin, sizeof(ficumin), &str_length);
    if (status != napi_ok) {
        napi_throw_error(env, NULL, "Failed to extract ficumin parameter");
        return NULL;
    }
    
    // Extract ficumout string (args[1])
    status = napi_get_value_string_utf8(env, args[1], ficumout, sizeof(ficumout), &str_length);
    if (status != napi_ok) {
        napi_throw_error(env, NULL, "Failed to extract ficumout parameter");
        return NULL;
    }
    
    // Extract dirtables string (args[2])
    status = napi_get_value_string_utf8(env, args[2], dirtables, sizeof(dirtables), &str_length);
    if (status != napi_ok) {
        napi_throw_error(env, NULL, "Failed to extract dirtables parameter");
        return NULL;
    }
    
    // Extract log flag (args[3])
    status = napi_get_value_int32(env, args[3], &log_flag);
    if (status != napi_ok) {
        napi_throw_error(env, NULL, "Failed to extract log flag parameter");
        return NULL;
    }
    
    // Extract gestion_portee (args[4])
    status = napi_get_value_int32(env, args[4], &gestion_portee);
    if (status != napi_ok) {
        napi_throw_error(env, NULL, "Failed to extract gestion_portee parameter");
        return NULL;
    }
    
    // Extract finess_geo (args[5])
    status = napi_get_value_int32(env, args[5], &finess_geo);
    if (status != napi_ok) {
        napi_throw_error(env, NULL, "Failed to extract finess_geo parameter");
        return NULL;
    }
    
    // Call the original CtrlFicUM function
    int res = CtrlFicUM(ficumin, ficumout, dirtables, log_flag, gestion_portee, finess_geo);
        
    // Create return object
    napi_value return_obj;
    status = napi_create_object(env, &return_obj);
    assert(status == napi_ok);
    
    // Add return code
    napi_value ret_val;
    status = napi_create_int32(env, res, &ret_val);
    assert(status == napi_ok);
    status = napi_set_named_property(env, return_obj, "returnCode", ret_val);
    assert(status == napi_ok);
    
    // Add success flag
    napi_value success_val;
    status = napi_get_boolean(env, res == 0, &success_val);
    assert(status == napi_ok);
    status = napi_set_named_property(env, return_obj, "success", success_val);
    assert(status == napi_ok);
    
    // Add error message if there was an error
    if (res != 0) {
        const char* msgerr_ium;
        switch(res) {
            case 1: msgerr_ium = "impossible d'ouvrir le fichier"; break;
            case 2: msgerr_ium = "impossible de creer le fichier de travail"; break;
            case 3: msgerr_ium = "impossible de creer le fichier de rapport"; break;
            case 4: msgerr_ium = "erreurs de format ou dates incoherentes detectees"; break;
            case 5: msgerr_ium = "au moins deux dates de debut d'autorisation identiques"; break;
            case 6: msgerr_ium = "erreur systeme"; break;
            case 8: msgerr_ium = "Type d'autorisation non acceptee avec l'UM reservee $$$$"; break;
            case 9: msgerr_ium = "fichier de references des autorisations d'UM corrompu"; break;
            case 10: msgerr_ium = "au moins deux dates de debut d'autorisation identiques pour une autorisation globale au finess geographique"; break;
            case 11: msgerr_ium = "Le type d'autorisation 72 IVG n'est plus accepte au 1er mars 2019."; break;
            default: msgerr_ium = "erreur inconnue."; break;
        }
        
        napi_value error_msg_val;
        status = napi_create_string_utf8(env, msgerr_ium, NAPI_AUTO_LENGTH, &error_msg_val);
        assert(status == napi_ok);
        status = napi_set_named_property(env, return_obj, "errorMessage", error_msg_val);
        assert(status == napi_ok);
    }
    
    return return_obj;
}

static napi_value Init(napi_env env, napi_value exports) {
    napi_status status;
    napi_property_descriptor desc[] = {
        DECLARE_NAPI_METHOD("main", Main)
    };
    status = napi_define_properties(env, exports, 1, desc);
    assert(status == napi_ok);
    return exports;
}

NAPI_MODULE(NODE_GYP_MODULE_NAME, Init) 