/*
 * Copyright (c) 2019, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

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

#include "aom_dsp/blend.h"
#include "aom_dsp/vmaf.h"
#include "aom_ports/system_state.h"

typedef struct FrameData {
  const YV12_BUFFER_CONFIG *source;
  const YV12_BUFFER_CONFIG *distorted;
  int frame_set;
  int bit_depth;
} FrameData;

static void vmaf_fatal_error(const char *message) {
  fprintf(stderr, "Fatal error: %s\n", message);
  exit(EXIT_FAILURE);
}

// A callback function used to pass data to VMAF.
// Returns 0 after reading a frame.
// Returns 2 when there is no more frame to read.
static int read_frame(float *ref_data, float *main_data, float *temp_data,
                      int stride, void *user_data) {
  FrameData *frames = (FrameData *)user_data;

  if (!frames->frame_set) {
    const int width = frames->source->y_width;
    const int height = frames->source->y_height;
    assert(width == frames->distorted->y_width);
    assert(height == frames->distorted->y_height);

    if (frames->source->flags & YV12_FLAG_HIGHBITDEPTH) {
      const float scale_factor = 1.0f / (float)(1 << (frames->bit_depth - 8));
      uint16_t *ref_ptr = CONVERT_TO_SHORTPTR(frames->source->y_buffer);
      uint16_t *main_ptr = CONVERT_TO_SHORTPTR(frames->distorted->y_buffer);

      for (int row = 0; row < height; ++row) {
        for (int col = 0; col < width; ++col) {
          ref_data[col] = scale_factor * (float)ref_ptr[col];
        }
        ref_ptr += frames->source->y_stride;
        ref_data += stride / sizeof(*ref_data);
      }

      for (int row = 0; row < height; ++row) {
        for (int col = 0; col < width; ++col) {
          main_data[col] = scale_factor * (float)main_ptr[col];
        }
        main_ptr += frames->distorted->y_stride;
        main_data += stride / sizeof(*main_data);
      }
    } else {
      uint8_t *ref_ptr = frames->source->y_buffer;
      uint8_t *main_ptr = frames->distorted->y_buffer;

      for (int row = 0; row < height; ++row) {
        for (int col = 0; col < width; ++col) {
          ref_data[col] = (float)ref_ptr[col];
        }
        ref_ptr += frames->source->y_stride;
        ref_data += stride / sizeof(*ref_data);
      }

      for (int row = 0; row < height; ++row) {
        for (int col = 0; col < width; ++col) {
          main_data[col] = (float)main_ptr[col];
        }
        main_ptr += frames->distorted->y_stride;
        main_data += stride / sizeof(*main_data);
      }
    }
    frames->frame_set = 1;
    return 0;
  }

  (void)temp_data;
  return 2;
}

void aom_calc_vmaf(const char *model_path, const YV12_BUFFER_CONFIG *source,
                   const YV12_BUFFER_CONFIG *distorted, const int bit_depth,
                   double *const vmaf) {
  aom_clear_system_state();
  const int width = source->y_width;
  const int height = source->y_height;
  FrameData frames = { source, distorted, 0, bit_depth };
  char *fmt = bit_depth == 10 ? "yuv420p10le" : "yuv420p";
  double vmaf_score;
  const int ret =
      compute_vmaf(&vmaf_score, fmt, width, height, read_frame,
                   /*user_data=*/&frames, (char *)model_path,
                   /*log_path=*/NULL, /*log_fmt=*/NULL, /*disable_clip=*/1,
                   /*disable_avx=*/0, /*enable_transform=*/0,
                   /*phone_model=*/0, /*do_psnr=*/0, /*do_ssim=*/0,
                   /*do_ms_ssim=*/0, /*pool_method=*/NULL, /*n_thread=*/0,
                   /*n_subsample=*/1, /*enable_conf_interval=*/0);
  if (ret) vmaf_fatal_error("Failed to compute VMAF scores.");

  aom_clear_system_state();
  *vmaf = vmaf_score;
}

void aom_calc_vmaf_multi_frame(void *user_data, const char *model_path,
                               int (*rd_frm)(float *ref_data, float *main_data,
                                             float *temp_data, int stride_byte,
                                             void *user_data),
                               int frame_width, int frame_height, int bit_depth,
                               double *vmaf) {
  aom_clear_system_state();

  char *fmt = bit_depth == 10 ? "yuv420p10le" : "yuv420p";
  double vmaf_score;
  const int ret = compute_vmaf(
      &vmaf_score, fmt, frame_width, frame_height, rd_frm,
      /*user_data=*/user_data, (char *)model_path,
      /*log_path=*/"vmaf_scores.xml", /*log_fmt=*/NULL, /*disable_clip=*/0,
      /*disable_avx=*/0, /*enable_transform=*/0,
      /*phone_model=*/0, /*do_psnr=*/0, /*do_ssim=*/0,
      /*do_ms_ssim=*/0, /*pool_method=*/NULL, /*n_thread=*/0,
      /*n_subsample=*/1, /*enable_conf_interval=*/0);
  FILE *vmaf_log = fopen("vmaf_scores.xml", "r");
  if (vmaf_log == NULL || ret) {
    vmaf_fatal_error("Failed to compute VMAF scores.");
  }

  int frame_index = 0;
  char buf[512];
  while (fgets(buf, 511, vmaf_log) != NULL) {
    if (memcmp(buf, "\t\t<frame ", 9) == 0) {
      char *p = strstr(buf, "vmaf=");
      if (p != NULL && p[5] == '"') {
        char *p2 = strstr(&p[6], "\"");
        *p2 = '\0';
        const double score = atof(&p[6]);
        if (score < 0.0 || score > 100.0) {
          vmaf_fatal_error("Failed to compute VMAF scores.");
        }
        vmaf[frame_index++] = score;
      }
    }
  }
  fclose(vmaf_log);

  aom_clear_system_state();
}
