/*!
* @file libharkio3_config.c
*
* @author Takeshi Mizumoto
* @version 0.1
* @brief  harkio_Config の API 群。 サンプリング周波数などの一般的な情報を表現する。
*/

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

#include "libharkio3.h"


/*!
 * @brief コンストラクタ。空の harkio_Config を作成する。
 * @return harkio_Config 型のポインタ。失敗すると NULL を返す。
 * @details 使用が終わったら、 harkio_TransferFunction_delete でメモリ解放を行う。
 */
harkio_Config* harkio_Config_new(void)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    harkio_Config *cfg = (harkio_Config *) calloc(sizeof(harkio_Config), 1);

    return cfg;
}

/*!
 * @brief デストラクタ。メンバになっている構造体を含めて全てのメモリを開放する。
 * @param[in] cfg  　　　開放したい伝達関数。解放後は NULL が代入される。
 */
void harkio_Config_delete(harkio_Config **cfg)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL || *cfg == NULL) {
        return;
    }

    if ((*cfg)->TSPpath) {
        free((*cfg)->TSPpath);
        (*cfg)->TSPpath = NULL;
    }

    if ((*cfg)->comment) {
        free((*cfg)->comment);
        (*cfg)->comment = NULL;
    }

    free((*cfg));
    *cfg = NULL;
}


/*!
 * @brief Getter。harkio_Config のコメントを返す
 * @param[in] cfg   harkio_Config
 * @return コメントを表す文字列へのポインタ
 */
char* harkio_Config_getComment(harkio_Config *cfg)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) return NULL;
    return cfg->comment;
}


/*!
 * @brief Getter。harkio_Config の同期加算回数を返す
 * @param[in] cfg   harkio_Config
 * @return 同期加算回数
 */
int harkio_Config_getSynchronousAverage(harkio_Config *cfg)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) return EXIT_FAILURE;
    return cfg->synchronousAverage;
}

/*!
 * @brief Getter。harkio_Config の TSP 信号のパスを返す
 * @param[in] cfg   harkio_Config
 * @return TSP 信号のパスを表す文字列へのポインタ
 */
char *harkio_Config_getTSPpath(harkio_Config *cfg)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) return NULL;
    return cfg->TSPpath;
}


int harkio_Config_getTSPoffset(harkio_Config *cfg)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) return EXIT_FAILURE;
    return cfg->TSPoffset;
}


int harkio_Config_getPeakSearchFrom(harkio_Config *cfg)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) return EXIT_FAILURE;
    return cfg->peakSearchFrom;
}


int harkio_Config_getPeakSearchTo(harkio_Config *cfg)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) return EXIT_FAILURE;
    return cfg->peakSearchTo;
}


int harkio_Config_getNfft(harkio_Config *cfg)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) return EXIT_FAILURE;
    return cfg->nfft;
}



int harkio_Config_getSamplingRate(harkio_Config *cfg)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) return EXIT_FAILURE;
    return cfg->samplingRate;
}



int harkio_Config_getTSPLength(harkio_Config *cfg)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) return EXIT_FAILURE;
    return cfg->TSPLength;
}



int harkio_Config_getSignalMax(harkio_Config *cfg)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) return EXIT_FAILURE;
    return cfg->signalMax;
}






int harkio_Config_setSynchronousAverage(harkio_Config *cfg, int value)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) {
        harkio_Log_printf(harkio_Log_Error, "Cfg is NULL");
        return EXIT_FAILURE;
    }

    if (value < 0) {
        harkio_Log_printf(harkio_Log_Error , "SynchronousAverage must not be negative.");
        return EXIT_FAILURE;
    }

    cfg->synchronousAverage = value;
    return EXIT_SUCCESS;
}



int harkio_Config_setTSPpath(harkio_Config *cfg, const char *value)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) {
        harkio_Log_printf(harkio_Log_Error, "Cfg is NULL");
        return EXIT_FAILURE;
    }

    if (cfg->TSPpath) {
        free(cfg->TSPpath);
        cfg->TSPpath = NULL;
    }

    if (value != NULL) {
        cfg->TSPpath = (char *) malloc(sizeof(char) * (strlen(value) + 1));
        strcpy(cfg->TSPpath, value);
    } else {
        cfg->TSPpath = NULL;
    }

    return EXIT_SUCCESS;
}



int harkio_Config_setTSPoffset(harkio_Config *cfg, int value)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) {
        harkio_Log_printf(harkio_Log_Error, "Cfg is NULL");
        return EXIT_FAILURE;
    }

    cfg->TSPoffset = value;
    return EXIT_SUCCESS;
}


int harkio_Config_setPeakSearchFrom(harkio_Config *cfg, int value)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) {
        harkio_Log_printf(harkio_Log_Error, "Cfg is NULL");
        return EXIT_FAILURE;
    }

    cfg->peakSearchFrom = value;
    return EXIT_SUCCESS;
}


int harkio_Config_setPeakSearchTo(harkio_Config *cfg, int value)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) {
        harkio_Log_printf(harkio_Log_Error, "Cfg is NULL");
        return EXIT_FAILURE;
    }

    if (value < cfg->peakSearchFrom) {
        harkio_Log_printf(harkio_Log_Error , "PeakSearchTo must be (value >= cfg->peakSearchFrom)");
        return EXIT_FAILURE;
    }

    cfg->peakSearchTo = value;
    return EXIT_SUCCESS;
}


int harkio_Config_setNfft(harkio_Config *cfg, int value)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) {
        harkio_Log_printf(harkio_Log_Error, "Cfg is NULL");
        return EXIT_FAILURE;
    }

    if (value <= 0) {
        harkio_Log_printf(harkio_Log_Warning , "Nfft must be (value > 0)");
        return EXIT_FAILURE;
    }
    cfg->nfft = value;
    return EXIT_SUCCESS;
}


int harkio_Config_setSamplingRate(harkio_Config *cfg, int value)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) {
        harkio_Log_printf(harkio_Log_Error, "Cfg is NULL");
        return EXIT_FAILURE;
    }

    if (value <= 0) {
        harkio_Log_printf(harkio_Log_Warning , "samplingRate must be (value > 0)");
        return EXIT_FAILURE;
    }
    cfg->samplingRate = value;
    return EXIT_SUCCESS;
}



int harkio_Config_setTSPlength(harkio_Config *cfg, int value)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) {
        harkio_Log_printf(harkio_Log_Error, "Cfg is NULL");
        return EXIT_FAILURE;
    }

    cfg->TSPLength = value;
    return EXIT_SUCCESS;
}





int harkio_Config_setSignalMax(harkio_Config *cfg, int value)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) {
        harkio_Log_printf(harkio_Log_Error, "Cfg is NULL");
        return EXIT_FAILURE;
    }

    cfg->signalMax = value;
    return EXIT_SUCCESS;
}




int harkio_Config_setComment(harkio_Config *cfg, const char *value)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (value == NULL) {
        harkio_Log_printf(harkio_Log_Warning ,"value");
        return EXIT_FAILURE;
    }

    if (cfg->comment) {
        free(cfg->comment);
        cfg->comment = NULL;
    }

    cfg->comment = NULL;
    if (value) {
        cfg->comment = (char *) malloc(sizeof(char) * (strlen(value) + 1));
        strcpy(cfg->comment, value);
    }
    return EXIT_SUCCESS;
}



int harkio_Config_isEqual(harkio_Config *a, harkio_Config *b)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    char *tmpa, *tmpb;

    if (a == NULL) {
        harkio_Log_printf(harkio_Log_Warning , "harkio_Config a is NULL");
        return 0;
    }

    if (b == NULL) {
        harkio_Log_printf(harkio_Log_Warning , "harkio_Config b is NULL");
        return 0;
    }


    if (harkio_Config_getSynchronousAverage(a) != harkio_Config_getSynchronousAverage(b)) {
        return 0;
    }

    tmpa = harkio_Config_getTSPpath(a);
    tmpb = harkio_Config_getTSPpath(b);

    if (tmpa != tmpb) {
        if (tmpa == NULL || tmpb == NULL) {
            return 0;
        }

        if (strcmp(tmpa, tmpb) != 0) {
            return 0;
        }
    }

    if (harkio_Config_getTSPoffset(a) != harkio_Config_getTSPoffset(b)) {
        return 0;
    }

    if (harkio_Config_getPeakSearchFrom(a) != harkio_Config_getPeakSearchFrom(b)) {
        return 0;
    }

    if (harkio_Config_getPeakSearchTo(a) != harkio_Config_getPeakSearchTo(b)) {
        return 0;
    }

    if (harkio_Config_getNfft(a) != harkio_Config_getNfft(b)) {
        return 0;
    }

    if (harkio_Config_getSamplingRate(a) != harkio_Config_getSamplingRate(b)) {
        return 0;
    }

    if (harkio_Config_getTSPLength(a) != harkio_Config_getTSPLength(b)) {
        return 0;
    }

    if (harkio_Config_getSignalMax(a) != harkio_Config_getSignalMax(b)) {
        return 0;
    }



    tmpa = harkio_Config_getComment(a);
    tmpb = harkio_Config_getComment(b);

    if (tmpa != tmpb) {
        if (tmpa == NULL || tmpb == NULL) {
            return 0;
        }

        if (strcmp(tmpa, tmpb) != 0) {
            return 0;
        }
    }

    return 1;
}

void harkio_Config_print(harkio_Config* cfg)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    char *buffer = harkio_Config_printBuffer(cfg);
    if (buffer)
        harkio_Log_printf(harkio_Log_Debug, buffer);
    free(buffer);
}

char* harkio_Config_printBuffer(harkio_Config* cfg)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg == NULL) {
        harkio_Log_printf(harkio_Log_Error, "Config is NULL");
        return NULL;
    }

    char* msg = (char*) malloc(MSG_LEN * sizeof(char));
    sprintf(msg, "Config: \n"
            "    comment: %s-\n"
            "    syncavg: %d\n"
            "    offset : %d\n"
            "    path   : %s-\n"
            "    from   : %d\n"
            "    to     : %d\n"
            "    nfft   : %d\n"
            "    sample : %d\n"
            "    TSPLength : %d\n"
            "    signalMax : %d\n",
            harkio_Config_getComment(cfg),
            harkio_Config_getSynchronousAverage(cfg),
            harkio_Config_getTSPoffset(cfg),
            harkio_Config_getTSPpath(cfg),
            harkio_Config_getPeakSearchFrom(cfg),
            harkio_Config_getPeakSearchTo(cfg),
            harkio_Config_getNfft(cfg),
            harkio_Config_getSamplingRate(cfg),
            harkio_Config_getTSPLength(cfg),
            harkio_Config_getSignalMax(cfg));

    return msg;
}



harkio_Config* harkio_Config_copy(harkio_Config *cfg1)
{
    harkio_Log_printf(harkio_Log_Trace, "@ %s", __func__);

    if (cfg1 == NULL) {
        harkio_Log_printf(harkio_Log_Error , "cfg1 is NULL");
        return NULL;
    }

    harkio_Config *cfg2 = harkio_Config_new();



    if (cfg2 == NULL) {
        harkio_Log_printf(harkio_Log_Error , "can not allocated memory");
        return NULL;
    }

    harkio_Config_setComment(cfg2, harkio_Config_getComment(cfg1));
    harkio_Config_setSynchronousAverage(cfg2, harkio_Config_getSynchronousAverage(cfg1));
    harkio_Config_setTSPpath(cfg2, harkio_Config_getTSPpath(cfg1));
    harkio_Config_setTSPoffset(cfg2, harkio_Config_getTSPoffset(cfg1));
    harkio_Config_setPeakSearchFrom(cfg2, harkio_Config_getPeakSearchFrom(cfg1));
    harkio_Config_setPeakSearchTo(cfg2, harkio_Config_getPeakSearchTo(cfg1));
    harkio_Config_setNfft(cfg2, harkio_Config_getNfft(cfg1));
    harkio_Config_setSamplingRate(cfg2, harkio_Config_getSamplingRate(cfg1));
    harkio_Config_setTSPlength(cfg2 , harkio_Config_getTSPLength(cfg1));
    harkio_Config_setSignalMax(cfg2, harkio_Config_getSignalMax(cfg1));
    return cfg2;
}

