/*
 * xcam_thread.h - xcam basic thread
 *
 *  Copyright (c) 2014 Intel Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: Wind Yuan <feng.yuan@intel.com>
 */


#include "xcam_cpf_reader.h"

#include <string.h>
#include <stdlib.h>
#include "libtbd.h"

#undef XCAM_FAIL_RETURN_VAL
#define XCAM_FAIL_RETURN_VAL(exp, ret) \
    if (!(exp)) {                  \
        XCAM_LOG_WARNING ("XCAM_FAIL_RETURN_VAL %s", #exp);  \
        return ret;                \
    }

#undef XCAM_FAIL_RETURN
#define XCAM_FAIL_RETURN(exp) \
    if (!(exp)) {                  \
        XCAM_LOG_WARNING ("XCAM_FAIL_RETURN %s", #exp);  \
        return ;                \
    }

void *xcam_new0(size_t size)
{
    void *buf = malloc (size);
    memset (buf, 0, size);
    return buf;
}

XCamCpfBlob * xcam_cpf_blob_new ()
{
    return (XCamCpfBlob*) xcam_new0 (sizeof(XCamCpfBlob));
}

void xcam_cpf_blob_free (XCamCpfBlob *blob)
{
    XCAM_FAIL_RETURN (blob);

    if (blob->data)
        xcam_free (blob->data);

    xcam_free (blob);
}

static int32_t
read_cpf_file (const char *cpf_file, uint8_t **buf)
{
    int32_t size = 0;
    FILE *fp = fopen (cpf_file, "rb");
    XCAM_FAIL_RETURN_VAL (fp, -1);

    *buf = NULL;

    if (fseek (fp, 0, SEEK_END) < 0)
        goto read_error;
    if ((size = ftell (fp)) <= 0)
        goto read_error;
    if (fseek( fp, 0, SEEK_SET) < 0)
        goto read_error;

    *buf = (uint8_t*) xcam_new0 (size);
    if (fread (*buf, 1, size, fp) != size)
        goto read_error;

    fclose (fp);
    return size;

read_error:
    XCAM_LOG_ERROR ("read cpf(%s) failed", cpf_file);
    fclose (fp);
    if (*buf) {
        xcam_free (*buf);
        *buf = NULL;
    }
    return -1;

}

boolean
xcam_cpf_read (const char *cpf_file, XCamCpfBlob *aiq_cpf, XCamCpfBlob *hal_cpf)
{
    uint8_t *cpf_buf;
    int32_t cpf_size;

    uint8_t *blob;
    int32_t blob_size;

    XCAM_FAIL_RETURN_VAL (cpf_file, FALSE);
    XCAM_FAIL_RETURN_VAL (aiq_cpf, FALSE);

    /* read cpf */
    if ((cpf_size = read_cpf_file(cpf_file, &cpf_buf)) <= 0) {
        XCAM_LOG_ERROR ("read cpf_file(%s) failed.", cpf_file);
        return FALSE;
    }

    /* check sum */
    if (tbd_validate (cpf_buf, cpf_size, tbd_tag_cpff) != tbd_err_none) {
        XCAM_LOG_ERROR ("tbd validate cpf file(%s) failed.", cpf_file);
        goto free_buf;
    }

    /* fetch AIQ */
    if ( (tbd_get_record (cpf_buf, tbd_class_aiq, tbd_format_any,
                          (void**)&blob, (size_t*)&blob_size) != tbd_err_none) ||
            !blob || blob_size <= 0) {
        XCAM_LOG_ERROR ("CPF parse AIQ record failed.");
        goto free_buf;
    }
    aiq_cpf->data = (uint8_t*) malloc (blob_size);
    aiq_cpf->size = blob_size;
    memcpy (aiq_cpf->data, blob, blob_size);


#if 0 //DRV not necessary
    /* fetch DRV */
    if (tbd_get_record (cpf_buf, tbd_class_drv, tbd_format_any,
                        &drv_blob.data, &drv_blob.size) != tbd_err_none) {
        XCAM_LOG_ERROR ("CPF parse DRV record failed.");
        return FALSE;
    }
#endif


    /* fetch HAL */
    if (hal_cpf) {
        if (tbd_get_record (cpf_buf, tbd_class_hal, tbd_format_any,
                            (void**)&blob, (size_t*)&blob_size) != tbd_err_none) {
            XCAM_LOG_WARNING ("CPF doesn't have HAL record.");
            // ignore HAL, not necessary
        } else if (blob && blob_size > 0) {
            hal_cpf->data = (uint8_t*) malloc (blob_size);
            hal_cpf->size = blob_size;
            memcpy (hal_cpf->data, blob, blob_size);
        }
    }

    xcam_free (cpf_buf);
    return TRUE;

free_buf:
    xcam_free (cpf_buf);
    return FALSE;

}
