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

// Human Presence Sensor Model

#include "hps.h"

#include <springbok.h>

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

#if !defined(NO_STATIC_INPUT)
#if HPS_IDX == 0
#include "hps_0_quant_input_c.h"
#define HPS_QUANT_INPUT hps_0_quant_input
#elif HPS_IDX == 2
#include "hps_2_quant_input_c.h"
#define HPS_QUANT_INPUT hps_2_quant_input
#elif HPS_IDX == 3
#include "hps_3_quant_input_c.h"
#define HPS_QUANT_INPUT hps_3_quant_input
#elif HPS_IDX == 4
#include "hps_4_quant_input_c.h"
#define HPS_QUANT_INPUT hps_4_quant_input
#elif HPS_IDX == 5
#include "hps_5_quant_input_c.h"
#define HPS_QUANT_INPUT hps_5_quant_input
#elif HPS_IDX == 6
#include "hps_6_quant_input_c.h"
#define HPS_QUANT_INPUT hps_6_quant_input
#else
#include "hps_1_quant_input_c.h"
#define HPS_QUANT_INPUT hps_1_quant_input
#endif
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) {
#if !defined(BUILD_EMITC)
  return &hps_bytecode_module_static_linked_llvm_cpu_library_query;
#else
  return &hps_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(
      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) {
  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);
  return result;
}
