/*
 * 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_ERROR) {
    return AOM_CODEC_ERROR;
  } else if (status == AOM_EXT_PART_TEST) {
    ext_part_controller->test_mode = 1;
    ext_part_controller->ready = 0;
    return AOM_CODEC_OK;
  }
  assert(status == AOM_EXT_PART_OK);
  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;
}
