/*
 * 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.
 */

// Human Presence Sensor Model

#include "hps.h"

#include <log.h>

#if !defined(NO_STATIC_INPUT)
#include HPS_QUANT_INPUT_C_H
static const void *kInput = HPS_QUANT_INPUT;
#else
static const void *kInput = (const void *)0x84000000;
#endif  // if !defined(NO_STATIC_INPUT)

// Compiled module embedded here to avoid file IO:
#if !defined(BUILD_EMITC)
#include "hps_bytecode_module_static.h"
#include "hps_bytecode_module_static_c.h"
#else
#include "hps_c_module_static_c.h"
#include "hps_c_module_static_emitc.h"
#endif

__attribute__((section(".model_output"))) HpsOutput score;

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_hps_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) {
  return &llvm_module_linked_llvm_cpu_library_query;
}

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(
      kInput, 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;
  score.score_0 = data[0];
  score.score_1 = data[1];

  LOG_INFO("Score 0: %d, Score 1: %d", score.score_0, score.score_1);

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