/*
 * Copyright 2022 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 <springbok.h>

#include "iree/base/api.h"
#include "iree/hal/api.h"

// Compiled module embedded here to avoid file IO:
#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
#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)
  const struct iree_file_toc_t *module_file_toc =
      quant_models_person_detection_bytecode_module_static_create();
  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
}

iree_hal_executable_library_query_fn_t library_query(void) {
#if !defined(BUILD_EMITC)
  return &person_detection_bytecode_module_static_linked_llvm_cpu_library_query;
#else
  return &person_detection_c_module_static_linked_llvm_cpu_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,
                             MlOutput *output) {
  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->result = &detection;
  output->len = sizeof(detection);

  return result;
}
