/*
 * Copyright (c) 2020
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <stdio.h>
#include <string.h>
#include <math.h>
#include "libavfilter/dnn/dnn_backend_native_layer_mathbinary.h"
#include "libavutil/avassert.h"

#define EPSON 0.00005

static float get_expected(float f1, float f2, DNNMathBinaryOperation op)
{
    switch (op)
    {
    case DMBO_SUB:
        return f1 - f2;
    case DMBO_ADD:
        return f1 + f2;
    case DMBO_MUL:
        return f1 * f2;
    case DMBO_REALDIV:
        return f1 / f2;
    default:
        av_assert0(!"not supported yet");
        return 0.f;
    }
}

static int test_broadcast_input0(DNNMathBinaryOperation op)
{
    DnnLayerMathBinaryParams params;
    DnnOperand operands[2];
    int32_t input_indexes[1];
    float input[1*1*2*3] = {
        -3, 2.5, 2, -2.1, 7.8, 100
    };
    float *output;

    params.bin_op = op;
    params.input0_broadcast = 1;
    params.input1_broadcast = 0;
    params.v = 7.28;

    operands[0].data = input;
    operands[0].dims[0] = 1;
    operands[0].dims[1] = 1;
    operands[0].dims[2] = 2;
    operands[0].dims[3] = 3;
    operands[1].data = NULL;

    input_indexes[0] = 0;
    dnn_execute_layer_math_binary(operands, input_indexes, 1, &params);

    output = operands[1].data;
    for (int i = 0; i < sizeof(input) / sizeof(float); i++) {
        float expected_output = get_expected(params.v, input[i], op);
        if (fabs(output[i] - expected_output) > EPSON) {
            printf("op %d, at index %d, output: %f, expected_output: %f (%s:%d)\n",
                    op, i, output[i], expected_output, __FILE__, __LINE__);
            av_freep(&output);
            return 1;
        }
    }

    av_freep(&output);
    return 0;
}

static int test_broadcast_input1(DNNMathBinaryOperation op)
{
    DnnLayerMathBinaryParams params;
    DnnOperand operands[2];
    int32_t input_indexes[1];
    float input[1*1*2*3] = {
        -3, 2.5, 2, -2.1, 7.8, 100
    };
    float *output;

    params.bin_op = op;
    params.input0_broadcast = 0;
    params.input1_broadcast = 1;
    params.v = 7.28;

    operands[0].data = input;
    operands[0].dims[0] = 1;
    operands[0].dims[1] = 1;
    operands[0].dims[2] = 2;
    operands[0].dims[3] = 3;
    operands[1].data = NULL;

    input_indexes[0] = 0;
    dnn_execute_layer_math_binary(operands, input_indexes, 1, &params);

    output = operands[1].data;
    for (int i = 0; i < sizeof(input) / sizeof(float); i++) {
        float expected_output = get_expected(input[i], params.v, op);
        if (fabs(output[i] - expected_output) > EPSON) {
            printf("op %d, at index %d, output: %f, expected_output: %f (%s:%d)\n",
                    op, i, output[i], expected_output, __FILE__, __LINE__);
            av_freep(&output);
            return 1;
        }
    }

    av_freep(&output);
    return 0;
}

static int test_no_broadcast(DNNMathBinaryOperation op)
{
    DnnLayerMathBinaryParams params;
    DnnOperand operands[3];
    int32_t input_indexes[2];
    float input0[1*1*2*3] = {
        -3, 2.5, 2, -2.1, 7.8, 100
    };
    float input1[1*1*2*3] = {
        -1, 2, 3, -21, 8, 10.0
    };
    float *output;

    params.bin_op = op;
    params.input0_broadcast = 0;
    params.input1_broadcast = 0;

    operands[0].data = input0;
    operands[0].dims[0] = 1;
    operands[0].dims[1] = 1;
    operands[0].dims[2] = 2;
    operands[0].dims[3] = 3;
    operands[1].data = input1;
    operands[1].dims[0] = 1;
    operands[1].dims[1] = 1;
    operands[1].dims[2] = 2;
    operands[1].dims[3] = 3;
    operands[2].data = NULL;

    input_indexes[0] = 0;
    input_indexes[1] = 1;
    dnn_execute_layer_math_binary(operands, input_indexes, 2, &params);

    output = operands[2].data;
    for (int i = 0; i < sizeof(input0) / sizeof(float); i++) {
        float expected_output = get_expected(input0[i], input1[i], op);
        if (fabs(output[i] - expected_output) > EPSON) {
            printf("op %d, at index %d, output: %f, expected_output: %f (%s:%d)\n",
                    op, i, output[i], expected_output, __FILE__, __LINE__);
            av_freep(&output);
            return 1;
        }
    }

    av_freep(&output);
    return 0;
}

static int test(DNNMathBinaryOperation op)
{
    if (test_broadcast_input0(op))
        return 1;

    if (test_broadcast_input1(op))
        return 1;

    if (test_no_broadcast(op))
        return 1;

    return 0;
}

int main(int argc, char **argv)
{
    if (test(DMBO_SUB))
        return 1;

    if (test(DMBO_ADD))
        return 1;

    if (test(DMBO_MUL))
        return 1;

    if (test(DMBO_REALDIV))
        return 1;

    return 0;
}
