// Copyright 2018 Xiaomi, Inc.  All rights reserved.
//
// 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.

// This is a generated file. DO NOT EDIT!

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "mace/public/mace.h"
#include "mace/public/mace_runtime.h"

namespace mace {

{% if model_type == 'code' %}
{% for tag in model_tags %}
namespace {{tag}} {

extern const unsigned char *LoadModelData(const std::string &model_data_file);

extern void UnloadModelData(const unsigned char *model_data);

extern const std::shared_ptr<NetDef> CreateNet();

extern const std::string ModelName();
extern const std::string ModelChecksum();
extern const std::string ModelBuildTime();
extern const std::string ModelBuildOptions();

}  // namespace {{tag}}
{% endfor %}

namespace {
std::map<std::string, int> model_name_map {
{% for i in range(model_tags |length) %}
  std::make_pair({{ model_tags[i]|tojson }}, {{ i }}),
{% endfor %}
};
}  // namespace

MaceStatus CreateMaceEngineFromCode(
    const std::string &model_name,
    const std::string &model_data_file,
    const std::vector<std::string> &input_nodes,
    const std::vector<std::string> &output_nodes,
    const DeviceType device_type,
    std::shared_ptr<MaceEngine> *engine) {
  // load model
  if (engine == nullptr) {
    return MaceStatus::MACE_INVALID_ARGS;
  }
  const unsigned char * model_data = nullptr;
  std::shared_ptr<NetDef> net_def;
  MaceStatus status = MaceStatus::MACE_SUCCESS;
  switch (model_name_map[model_name]) {
{% for i in range(model_tags |length) %}
   case {{ i }}:
    model_data =
        mace::{{model_tags[i]}}::LoadModelData(model_data_file);
    net_def = mace::{{model_tags[i]}}::CreateNet();
    engine->reset(new mace::MaceEngine(device_type));
    status = (*engine)->Init(net_def.get(), input_nodes, output_nodes, model_data);
    if (device_type == DeviceType::GPU || device_type == DeviceType::HEXAGON) {
      mace::{{model_tags[i]}}::UnloadModelData(model_data);
    }
    break;
{% endfor %}
   default:
     status = MaceStatus::MACE_INVALID_ARGS;
  }

  return status;
}
{% else %}
MaceStatus CreateMaceEngineFromCode(
    const std::string &model_name,
    const std::string &model_data_file,
    const std::vector<std::string> &input_nodes,
    const std::vector<std::string> &output_nodes,
    const DeviceType device_type,
    std::shared_ptr<MaceEngine> *engine) {
  (void)(model_name);
  (void)(model_data_file);
  (void)(input_nodes);
  (void)(output_nodes);
  (void)(device_type);
  (void)(engine);
  return MaceStatus::MACE_INVALID_ARGS;
}
{% endif %}

}  // namespace mace
