/****************************************************************************
** Leistungsorientierte Krankenanstaltenfinanzierung (LKF)                 **
** Scoring-C-Sourcen V2024.0                                               **
** (C) 2023 BMSGPK                                                         **
*****************************************************************************
** test5.c - Testfunktionen                                                **
**                                                                         **
**		 Alex.Holzer@chello.at                                             **
**       Bernhard.Pesec@dothealth.at                                       **
***************************************************************************/


#include "lkfint5.h"
#include "lkfstru5.h"
#include <ctype.h>
#include <math.h>

#include "lkf5test.h"

_SCORING_EXPORT LKF_TESTCONTEXT *lkf_alloc_testcontext(const char *stammPath)
{
    LKF_TESTCONTEXT *pTestContext = (LKF_TESTCONTEXT *) LKF_CALLOC(0, "lkf_alloc_testcontext", sizeof(LKF_TESTCONTEXT), 1);
    strcpy ((char *) pTestContext->stammPath, stammPath);
    return pTestContext;
}

_SCORING_EXPORT void lkf_free_testcontext(LKF_TESTCONTEXT *pContext) {
    if (pContext->buffer) {
        for (unsigned int i = 0; i < pContext->buffer_count; i++) {
            LKF_FREE(0, "lkf_free_testcontext.2", pContext->buffer[i]);
        }
        LKF_FREE(0, "reportIssue.2", pContext->buffer);
    }
    
    if (pContext->bufferPointer > 0) {
        LKF_FREE(0, "reportIssue", pContext->bufferPointer);
    }
    
    LKF_FREE(0, "lkf_alloc_testcontext", pContext);
}

static void reportIssue (LKF_TESTCONTEXT *pContext, const char *issue) {
    
    unsigned int len;
    char *bufStart;
    
    if (pContext->error_alloc == pContext->error_count) {
        char **old = pContext->bufferPointer;
        pContext->bufferPointer = (char **) LKF_CALLOC(0, "reportIssue", sizeof(char *), pContext->error_alloc += 100);
        if (!pContext->bufferPointer) {
            LKF_FREE(0, "reportIssue", old);
            return;
        }
        if (old) {
            memcpy (pContext->bufferPointer, old, pContext->error_count * sizeof(char *));
            LKF_FREE(0, "reportIssue", old);
        }
    }
    
    len = (unsigned int) strlen(issue);
    
    if (pContext->current_buffer_offset + len > pContext->current_buffer_alloc) {
        char *newBuffer;
        char **newBufferPointers;
        char **oldBuffers = pContext->buffer;
        newBufferPointers = (char **) LKF_CALLOC(0, "reportIssue.2", sizeof (char *), pContext->buffer_count + 1);
        if (!newBufferPointers) return;
        newBuffer = (char *) LKF_MALLOC (0, "reportIssue.3", pContext->current_buffer_alloc);
        if (!newBuffer) {
            LKF_FREE(0, "reportIssue.2", newBufferPointers);
            return;
        }
        pContext->buffer = newBufferPointers;
        if (oldBuffers != 0) {
            memcpy (pContext->buffer, oldBuffers, sizeof(char *) * pContext->buffer_count);
            LKF_FREE(0, "reportIssue.2", oldBuffers);
        }
        pContext->current_buffer_alloc = 32000;
        pContext->current_buffer_offset = 0;
        
        pContext->buffer[pContext->buffer_count++] = (char *) newBuffer;
    }
    
    bufStart = pContext->buffer[pContext->buffer_count-1] + pContext->current_buffer_offset;
    pContext->bufferPointer[pContext->error_count++] = bufStart;
    memcpy (bufStart, issue, len + 1);
    pContext->current_buffer_offset += len + 1;
}

_SCORING_EXPORT unsigned int lkf_test_getIssueCount (LKF_TESTCONTEXT *testContext) {
    return testContext->error_count;
}

_SCORING_EXPORT const char *lkf_test_getIssue (LKF_TESTCONTEXT *testContext, unsigned int i) {
    return testContext->bufferPointer[i];
}

_SCORING_EXPORT unsigned int lkf_test_utils (LKF_TESTCONTEXT *testContext) {
    LKF_EXPANDED_LINE_INFO info;
    LKF_CONTEXT *pContext;
    LKF_EXPANDED_LINE *pExpandLine;
    SATZART_FELD feld1 = {I11_BLUTBILD_PH,                TYP_FLOAT, 139,  4, 0, 0, "BLUTBILD: PH-WERT"};
    char error[1024];
    double v;
    
    memset (&info, 0, sizeof (LKF_EXPANDED_LINE_INFO));
    pContext = lkf_alloc_context(2018, testContext->stammPath, error);
    lkf_set_modelljahr(pContext, 2018, 0, error);
    if (!lkf_alloc_kk_context(pContext)) return LKF_OUTOFMEMORY_UINTERROR;
    
    pExpandLine = lkf_create_expandLine(pContext, "I11|K901|1180179664||20180401|001|20180401|10|0|1|0|0|00|0|0|1|0|3|0|2||7,52||19|2|6|5|4|084|000000000000000000000|38,1|1|133,0|030|000,0||097|011|3", 0, &info, "lkf_test_utils");
    
    if (Satzart_GetValueFloat((const char *) pExpandLine, LKF_LEN_FOR_EXPANDEDLINE, &feld1, &v, 0) != 0) {
        reportIssue(testContext, "I01: Error parsing ph");
    }
    else if (v != 7.52) {
        sprintf (error, "I002: Error - wrong number (%5.2f vs 7.52)", v);
        reportIssue(testContext, error);
    }
    
    lkf_free_expandLine(pContext, pExpandLine);
    // TODO: check minus
    //pExpandLine = lkf_create_expandLine(pContext, "", 0, &info);
    //lkf_free_expandLine(pExpandLine);
    
    lkf_free_context(pContext);
    return 2;
}

_SCORING_EXPORT unsigned int lkf_test_aufenthalt1 (LKF_TESTCONTEXT *testContext)
{
    LKF_CONTEXT *pContext;
    LKF_AUFENTHALT *pAufenthalt;
    char line[512];
    char error[1024];
    const char *expected;
    
    pContext = lkf_alloc_context(2019, testContext->stammPath, error);
    lkf_set_modelljahr(pContext, 2018, 0, error);
    
    pAufenthalt = lkf_alloc_aufenthalt_context(pContext);
    lkf_add_line_auf(pAufenthalt, "X01|K714|1234||20190621|1200|S|19360501|80|M|AT|AT|1010|90101|A|P||||E|20190621|1200|11|J|0");
    lkf_add_line_auf(pAufenthalt, "X02|K714|1234||20190621|01|11111100|20190621||J||||||N|80|");
    lkf_add_line_auf(pAufenthalt, "X03|K714|1234||20190621|I51.9|H|D||");
    lkf_add_line_auf(pAufenthalt, "X04|K714|1234||20190621|BG020||J|0001|20190621|2024|18111600|");
    lkf_plaus(pContext, pAufenthalt);
    lkf_scoring(pContext, pAufenthalt);
    lkf_auf_line_scoring(pAufenthalt, line);
    
    expected = "X05|K714|1234||20190621|HDG06.04|A|||36|30|||||66";
    
    if (strcmp (line, expected)) {
        sprintf (error, "I100: Different C result: %s (exp: %s)", line, expected);
        reportIssue(testContext, error);
    }
    
    lkf_reset_aufenthalt(pAufenthalt);
    lkf_add_line_auf(pAufenthalt, "X01|K714|1234||20190621|1200|S|19360501|80|M|AT|AT|1010|90101|A|P||||E|20190621|1200|11|J|0");
    lkf_add_line_auf(pAufenthalt, "X02|K714|1234||20190621|01|11111100|20190621||J||||||N|80|");
    lkf_add_line_auf(pAufenthalt, "X03|K714|1234||20190621|I51.9|H|D||");
    lkf_add_line_auf(pAufenthalt, "X04|K714|1234||20190621|BG020||J|0001|20190621|2024|18111600|");
    lkf_plaus(pContext, pAufenthalt);
    lkf_scoring(pContext, pAufenthalt);
    lkf_auf_line_scoring(pAufenthalt, line);
    if (strcmp (line, expected)) {
        sprintf (error, "I100: Different C result: %s (exp: %s)", line, expected);
        reportIssue(testContext, error);
    }
    lkf_free_aufenthalt(pAufenthalt);
    lkf_free_context(pContext);
    return 2;
}

