/*
 * Copyright 2023 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Person_detection quant model
// MlModel struct initialization to include model I/O info.
// Bytecode loading, input/output processes.

#include "person_detection.h"

#include <log.h>

// Compiled module embedded here to avoid file IO:
#if defined(BUILD_VMVX)
#if !defined(BUILD_EMITC)
#include "person_detection_bytecode_module_vmvx_c.h"
#else
#include "person_detection_c_module_vmvx_emitc.h"
#endif  // !defined(BUILD_EMITC)
#else
#if !defined(BUILD_EMITC)
#include "person_detection_bytecode_module_static.h"
#include "person_detection_bytecode_module_static_c.h"
#else
#include "person_detection_c_module_static_c.h"
#include "person_detection_c_module_static_emitc.h"
#endif  // !defined(BUILD_EMITC)
#endif  // defined(BUILD_VMVX)
#include "person_detection_quant_input_c.h"

__attribute__((section(".model_output"))) PersonDetectionOutput detection;

iree_status_t create_module(iree_vm_instance_t *instance,
                            iree_vm_module_t **module) {
#if !defined(BUILD_EMITC)
#if defined(BUILD_VMVX)
  const struct iree_file_toc_t *module_file_toc =
      quant_models_person_detection_bytecode_module_vmvx_create();
#else
  const struct iree_file_toc_t *module_file_toc =
      quant_models_person_detection_bytecode_module_static_create();
#endif
  return iree_vm_bytecode_module_create(
      instance,
      iree_make_const_byte_span(module_file_toc->data, module_file_toc->size),
      iree_allocator_null(), iree_allocator_system(), module);
#else
  return module_create(instance, iree_allocator_system(), module);
#endif
}

#if !defined(BUILD_VMVX)
iree_hal_executable_library_query_fn_t library_query(void) {
  return &module_linked_library_query;
}
#endif

iree_status_t load_input_data(const MlModel *model, void **buffer,
                              iree_const_byte_span_t **byte_span) {
  byte_span[0] = malloc(sizeof(iree_const_byte_span_t));
  *byte_span[0] = iree_make_const_byte_span(
      person_detection_quant_input,
      model->input_size_bytes[0] * model->input_length[0]);
  return iree_ok_status();
}

iree_status_t process_output(const MlModel *model,
                             iree_hal_buffer_mapping_t *buffers,
                             uint32_t *output_length, uint32_t *output_ptr) {
  iree_status_t result = iree_ok_status();
  int8_t *data = (int8_t *)buffers[0].contents.data;
  detection.non_person_score = data[0];
  detection.person_score = data[1];

  LOG_INFO("Output: Non-person Score: %d; Person Score: %d",
           detection.non_person_score, detection.person_score);

  *output_length = sizeof(detection);
  *output_ptr = (uint32_t)&detection;
  return result;
}
