/*
 * Copyright © 2018, VideoLAN and dav1d authors
 * Copyright © 2018, Two Orioles, LLC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "dav1d/data.h"

#include "common/attributes.h"
#include "common/validate.h"

#include "src/data.h"
#include "src/ref.h"

uint8_t *dav1d_data_create_internal(Dav1dData *const buf, const size_t sz) {
    validate_input_or_ret(buf != NULL, NULL);

    buf->ref = dav1d_ref_create(sz);
    if (!buf->ref) return NULL;
    buf->data = buf->ref->const_data;
    buf->sz = buf->m.size = sz;
    dav1d_data_props_set_defaults(&buf->m);

    return buf->ref->data;
}

int dav1d_data_wrap_internal(Dav1dData *const buf, const uint8_t *const ptr,
                             const size_t sz,
                             void (*const free_callback)(const uint8_t *data,
                                                         void *cookie),
                             void *const cookie)
{
    validate_input_or_ret(buf != NULL, DAV1D_ERR(EINVAL));
    validate_input_or_ret(ptr != NULL, DAV1D_ERR(EINVAL));
    validate_input_or_ret(free_callback != NULL, DAV1D_ERR(EINVAL));

    buf->ref = dav1d_ref_wrap(ptr, free_callback, cookie);
    if (!buf->ref) return DAV1D_ERR(ENOMEM);
    buf->data = ptr;
    buf->sz = buf->m.size = sz;
    dav1d_data_props_set_defaults(&buf->m);

    return 0;
}

int dav1d_data_wrap_user_data_internal(Dav1dData *const buf,
                                       const uint8_t *const user_data,
                                       void (*const free_callback)(const uint8_t *user_data,
                                                                   void *cookie),
                                       void *const cookie)
{
    validate_input_or_ret(buf != NULL, DAV1D_ERR(EINVAL));
    validate_input_or_ret(free_callback != NULL, DAV1D_ERR(EINVAL));

    buf->m.user_data.ref = dav1d_ref_wrap(user_data, free_callback, cookie);
    if (!buf->m.user_data.ref) return DAV1D_ERR(ENOMEM);
    buf->m.user_data.data = user_data;

    return 0;
}


void dav1d_data_ref(Dav1dData *const dst, const Dav1dData *const src) {
    validate_input(dst != NULL);
    validate_input(dst->data == NULL);
    validate_input(src != NULL);

    if (src->ref) {
        validate_input(src->data != NULL);
        dav1d_ref_inc(src->ref);
    }
    if (src->m.user_data.ref) dav1d_ref_inc(src->m.user_data.ref);
    *dst = *src;
}

void dav1d_data_move_ref(Dav1dData *const dst, Dav1dData *const src) {
    validate_input(dst != NULL);
    validate_input(dst->data == NULL);
    validate_input(src != NULL);

    if (src->ref)
        validate_input(src->data != NULL);

    *dst = *src;
    memset(src, 0, sizeof(*src));
}

void dav1d_data_props_copy(Dav1dDataProps *const dst,
                           const Dav1dDataProps *const src)
{
    assert(dst != NULL);
    assert(src != NULL);

    dav1d_ref_dec(&dst->user_data.ref);
    *dst = *src;
    if (dst->user_data.ref) dav1d_ref_inc(dst->user_data.ref);
}

void dav1d_data_props_set_defaults(Dav1dDataProps *const props) {
    assert(props != NULL);

    props->timestamp = INT64_MIN;
    props->duration = 0;
    props->offset = -1;
    props->user_data.data = NULL;
    props->user_data.ref = NULL;
}

void dav1d_data_unref_internal(Dav1dData *const buf) {
    validate_input(buf != NULL);

    struct Dav1dRef *user_data_ref = buf->m.user_data.ref;
    if (buf->ref) {
        validate_input(buf->data != NULL);
        dav1d_ref_dec(&buf->ref);
    }
    memset(buf, 0, sizeof(*buf));
    dav1d_ref_dec(&user_data_ref);
}
