/*
 * Copyright (c) 2016, 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.
 */

/*!\file
 * \brief Provides the high level interface to wrap decoder algorithms.
 *
 */
#include <stdarg.h>
#include <stdlib.h>

#include "config/aom_config.h"
#include "config/aom_version.h"

#include "aom/aom_integer.h"
#include "aom/internal/aom_codec_internal.h"

int aom_codec_version(void) { return VERSION_PACKED; }

const char *aom_codec_version_str(void) { return VERSION_STRING_NOSP; }

const char *aom_codec_version_extra_str(void) { return VERSION_EXTRA; }

const char *aom_codec_iface_name(aom_codec_iface_t *iface) {
  return iface ? iface->name : "<invalid interface>";
}

const char *aom_codec_err_to_string(aom_codec_err_t err) {
  switch (err) {
    case AOM_CODEC_OK: return "Success";
    case AOM_CODEC_ERROR: return "Unspecified internal error";
    case AOM_CODEC_MEM_ERROR: return "Memory allocation error";
    case AOM_CODEC_ABI_MISMATCH: return "ABI version mismatch";
    case AOM_CODEC_INCAPABLE:
      return "Codec does not implement requested capability";
    case AOM_CODEC_UNSUP_BITSTREAM:
      return "Bitstream not supported by this decoder";
    case AOM_CODEC_UNSUP_FEATURE:
      return "Bitstream required feature not supported by this decoder";
    case AOM_CODEC_CORRUPT_FRAME: return "Corrupt frame detected";
    case AOM_CODEC_INVALID_PARAM: return "Invalid parameter";
    case AOM_CODEC_LIST_END: return "End of iterated list";
  }

  return "Unrecognized error code";
}

const char *aom_codec_error(const aom_codec_ctx_t *ctx) {
  return (ctx) ? aom_codec_err_to_string(ctx->err)
               : aom_codec_err_to_string(AOM_CODEC_INVALID_PARAM);
}

const char *aom_codec_error_detail(const aom_codec_ctx_t *ctx) {
  if (ctx && ctx->err)
    return ctx->priv ? ctx->priv->err_detail : ctx->err_detail;

  return NULL;
}

aom_codec_err_t aom_codec_destroy(aom_codec_ctx_t *ctx) {
  if (!ctx) {
    return AOM_CODEC_INVALID_PARAM;
  }
  if (!ctx->iface || !ctx->priv) {
    ctx->err = AOM_CODEC_ERROR;
    return AOM_CODEC_ERROR;
  }
  ctx->iface->destroy((aom_codec_alg_priv_t *)ctx->priv);
  ctx->iface = NULL;
  ctx->name = NULL;
  ctx->priv = NULL;
  ctx->err = AOM_CODEC_OK;
  return AOM_CODEC_OK;
}

aom_codec_caps_t aom_codec_get_caps(aom_codec_iface_t *iface) {
  return iface ? iface->caps : 0;
}

aom_codec_err_t aom_codec_control(aom_codec_ctx_t *ctx, int ctrl_id, ...) {
  if (!ctx) {
    return AOM_CODEC_INVALID_PARAM;
  }
  // Control ID must be non-zero.
  if (!ctrl_id) {
    ctx->err = AOM_CODEC_INVALID_PARAM;
    return AOM_CODEC_INVALID_PARAM;
  }
  if (!ctx->iface || !ctx->priv || !ctx->iface->ctrl_maps) {
    ctx->err = AOM_CODEC_ERROR;
    return AOM_CODEC_ERROR;
  }

  // "ctrl_maps" is an array of (control ID, function pointer) elements,
  // with CTRL_MAP_END as a sentinel.
  for (aom_codec_ctrl_fn_map_t *entry = ctx->iface->ctrl_maps;
       !at_ctrl_map_end(entry); ++entry) {
    if (entry->ctrl_id == ctrl_id) {
      va_list ap;
      va_start(ap, ctrl_id);
      ctx->err = entry->fn((aom_codec_alg_priv_t *)ctx->priv, ap);
      va_end(ap);
      return ctx->err;
    }
  }
  ctx->err = AOM_CODEC_ERROR;
  ctx->priv->err_detail = "Invalid control ID";
  return AOM_CODEC_ERROR;
}

aom_codec_err_t aom_codec_set_option(aom_codec_ctx_t *ctx, const char *name,
                                     const char *value) {
  if (!ctx) {
    return AOM_CODEC_INVALID_PARAM;
  }
  if (!ctx->iface || !ctx->priv || !ctx->iface->set_option) {
    ctx->err = AOM_CODEC_ERROR;
    return AOM_CODEC_ERROR;
  }
  ctx->err =
      ctx->iface->set_option((aom_codec_alg_priv_t *)ctx->priv, name, value);
  return ctx->err;
}

void aom_internal_error(struct aom_internal_error_info *info,
                        aom_codec_err_t error, const char *fmt, ...) {
  va_list ap;

  info->error_code = error;
  info->has_detail = 0;

  if (fmt) {
    size_t sz = sizeof(info->detail);

    info->has_detail = 1;
    va_start(ap, fmt);
    vsnprintf(info->detail, sz - 1, fmt, ap);
    va_end(ap);
    info->detail[sz - 1] = '\0';
  }

  if (info->setjmp) longjmp(info->jmp, info->error_code);
}

void aom_merge_corrupted_flag(int *corrupted, int value) {
  *corrupted |= value;
}

const char *aom_obu_type_to_string(OBU_TYPE type) {
  switch (type) {
    case OBU_SEQUENCE_HEADER: return "OBU_SEQUENCE_HEADER";
    case OBU_TEMPORAL_DELIMITER: return "OBU_TEMPORAL_DELIMITER";
    case OBU_FRAME_HEADER: return "OBU_FRAME_HEADER";
    case OBU_REDUNDANT_FRAME_HEADER: return "OBU_REDUNDANT_FRAME_HEADER";
    case OBU_FRAME: return "OBU_FRAME";
    case OBU_TILE_GROUP: return "OBU_TILE_GROUP";
    case OBU_METADATA: return "OBU_METADATA";
    case OBU_TILE_LIST: return "OBU_TILE_LIST";
    case OBU_PADDING: return "OBU_PADDING";
    default: break;
  }
  return "<Invalid OBU Type>";
}
