/*
 * Copyright (c) 2021, 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 "av1/common/common.h"
#include "av1/encoder/external_partition.h"

aom_codec_err_t av1_ext_part_create(aom_ext_part_funcs_t funcs,
                                    aom_ext_part_config_t config,
                                    ExtPartController *ext_part_controller) {
  if (ext_part_controller == NULL) {
    return AOM_CODEC_INVALID_PARAM;
  }
  ext_part_controller->funcs = funcs;
  ext_part_controller->config = config;
  const aom_ext_part_status_t status = ext_part_controller->funcs.create_model(
      ext_part_controller->funcs.priv, &ext_part_controller->config,
      &ext_part_controller->model);
  if (status != AOM_EXT_PART_OK) {
    return AOM_CODEC_ERROR;
  }
  ext_part_controller->ready = 1;
  return AOM_CODEC_OK;
}

aom_codec_err_t av1_ext_part_init(ExtPartController *ext_part_controller) {
  if (ext_part_controller == NULL) {
    return AOM_CODEC_INVALID_PARAM;
  }
  av1_zero(ext_part_controller);
  return AOM_CODEC_OK;
}

aom_codec_err_t av1_ext_part_delete(ExtPartController *ext_part_controller) {
  if (ext_part_controller == NULL) {
    return AOM_CODEC_INVALID_PARAM;
  }
  if (ext_part_controller->ready) {
    const aom_ext_part_status_t status =
        ext_part_controller->funcs.delete_model(&ext_part_controller->model);
    if (status != AOM_EXT_PART_OK) {
      return AOM_CODEC_ERROR;
    }
  }
  return av1_ext_part_init(ext_part_controller);
}

bool av1_ext_part_get_partition_decision(ExtPartController *ext_part_controller,
                                         aom_partition_decision_t *decision) {
  assert(ext_part_controller != NULL);
  assert(ext_part_controller->ready);
  assert(decision != NULL);
  const aom_ext_part_status_t status =
      ext_part_controller->funcs.get_partition_decision(
          &ext_part_controller->model, decision);
  if (status != AOM_EXT_PART_OK) return false;
  return true;
}

bool av1_ext_part_send_partition_stats(ExtPartController *ext_part_controller,
                                       const aom_partition_stats_t *stats) {
  assert(ext_part_controller != NULL);
  assert(ext_part_controller->ready);
  assert(stats != NULL);
  const aom_ext_part_status_t status =
      ext_part_controller->funcs.send_partition_stats(
          &ext_part_controller->model, stats);
  if (status != AOM_EXT_PART_OK) return false;
  return true;
}

bool av1_ext_part_send_features(ExtPartController *ext_part_controller,
                                const aom_partition_features_t *features) {
  assert(ext_part_controller != NULL);
  assert(ext_part_controller->ready);
  assert(features != NULL);
  const aom_ext_part_status_t status = ext_part_controller->funcs.send_features(
      &ext_part_controller->model, features);
  if (status != AOM_EXT_PART_OK) return false;
  return true;
}
