/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * 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.
 */
//#define LOG_NDEBUG 0
#define LOG_TAG "Metadata"

#include <errno.h>

#include <system/camera_metadata.h>

#include <log/log.h>

#define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
#include <utils/Trace.h>

#include "Metadata.h"

namespace default_camera_hal {

Metadata::Metadata():
    mData(NULL)
{
}

Metadata::~Metadata()
{
    replace(NULL);
}

void Metadata::replace(camera_metadata_t *m)
{
    if (m == mData) {
        ALOGE("%s: Replacing metadata with itself?!", __func__);
        return;
    }
    if (mData)
        free_camera_metadata(mData);
    mData = m;
}

int Metadata::init(const camera_metadata_t *metadata)
{
    camera_metadata_t* tmp;

    if (validate_camera_metadata_structure(metadata, NULL))
        return -EINVAL;

    tmp = clone_camera_metadata(metadata);
    if (tmp == NULL)
        return -EINVAL;

    replace(tmp);
    return 0;
}

int Metadata::addUInt8(uint32_t tag, int count, const uint8_t *data)
{
    if (!validate(tag, TYPE_BYTE, count)) return -EINVAL;
    return add(tag, count, data);
}

int Metadata::add1UInt8(uint32_t tag, const uint8_t data)
{
    return addUInt8(tag, 1, &data);
}

int Metadata::addInt32(uint32_t tag, int count, const int32_t *data)
{
    if (!validate(tag, TYPE_INT32, count)) return -EINVAL;
    return add(tag, count, data);
}

int Metadata::addFloat(uint32_t tag, int count, const float *data)
{
    if (!validate(tag, TYPE_FLOAT, count)) return -EINVAL;
    return add(tag, count, data);
}

int Metadata::addInt64(uint32_t tag, int count, const int64_t *data)
{
    if (!validate(tag, TYPE_INT64, count)) return -EINVAL;
    return add(tag, count, data);
}

int Metadata::addDouble(uint32_t tag, int count, const double *data)
{
    if (!validate(tag, TYPE_DOUBLE, count)) return -EINVAL;
    return add(tag, count, data);
}

int Metadata::addRational(uint32_t tag, int count,
        const camera_metadata_rational_t *data)
{
    if (!validate(tag, TYPE_RATIONAL, count)) return -EINVAL;
    return add(tag, count, data);
}

bool Metadata::validate(uint32_t tag, int tag_type, int count)
{
    if (get_camera_metadata_tag_type(tag) < 0) {
        ALOGE("%s: Invalid metadata entry tag: %d", __func__, tag);
        return false;
    }
    if (tag_type < 0 || tag_type >= NUM_TYPES) {
        ALOGE("%s: Invalid metadata entry tag type: %d", __func__, tag_type);
        return false;
    }
    if (tag_type != get_camera_metadata_tag_type(tag)) {
        ALOGE("%s: Tag %d called with incorrect type: %s(%d)", __func__, tag,
                camera_metadata_type_names[tag_type], tag_type);
        return false;
    }
    if (count < 1) {
        ALOGE("%s: Invalid metadata entry count: %d", __func__, count);
        return false;
    }
    return true;
}

int Metadata::add(uint32_t tag, int count, const void *tag_data)
{
    int res;
    size_t entry_capacity = 0;
    size_t data_capacity = 0;
    camera_metadata_t* tmp;
    int tag_type = get_camera_metadata_tag_type(tag);
    size_t size = calculate_camera_metadata_entry_data_size(tag_type, count);

    if (NULL == mData) {
        entry_capacity = 1;
        data_capacity = size;
    } else {
        entry_capacity = get_camera_metadata_entry_count(mData) + 1;
        data_capacity = get_camera_metadata_data_count(mData) + size;
    }

    // Opportunistically attempt to add if metadata exists and has room for it
    if (mData && !add_camera_metadata_entry(mData, tag, tag_data, count))
        return 0;
    // Double new dimensions to minimize future reallocations
    tmp = allocate_camera_metadata(entry_capacity * 2, data_capacity * 2);
    if (tmp == NULL) {
        ALOGE("%s: Failed to allocate new metadata with %zu entries, %zu data",
                __func__, entry_capacity, data_capacity);
        return -ENOMEM;
    }
    // Append the current metadata to the new (empty) metadata, if any
    if (NULL != mData) {
      res = append_camera_metadata(tmp, mData);
      if (res) {
          ALOGE("%s: Failed to append old metadata %p to new %p",
                  __func__, mData, tmp);
          return res;
      }
    }
    // Add the remaining new item to tmp and replace mData
    res = add_camera_metadata_entry(tmp, tag, tag_data, count);
    if (res) {
        ALOGE("%s: Failed to add new entry (%d, %p, %d) to metadata %p",
                __func__, tag, tag_data, count, tmp);
        return res;
    }
    replace(tmp);

    return 0;
}

camera_metadata_t* Metadata::get()
{
    return mData;
}

} // namespace default_camera_hal
