/*
 * ObjectBox Generator - a build time tool for ObjectBox
 * Copyright (C) 2018-2024 ObjectBox Ltd. All rights reserved.
 * https://objectbox.io
 *
 * This file is part of ObjectBox Generator.
 *
 * ObjectBox Generator is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * ObjectBox Generator is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with ObjectBox Generator.  If not, see <http://www.gnu.org/licenses/>.
 */

package templates

import (
	"text/template"
)

// CppBindingTemplateHeader is used to generated the binding code
var CppBindingTemplateHeader = template.Must(template.New("binding-hpp").Funcs(funcMap).Parse(
	`// Code generated by ObjectBox; DO NOT EDIT.

#pragma once

#include <cstdbool>
#include <cstdint>
{{- if eq "std::optional" .Optional}} 
#include <optional>
{{- else if .Optional}}
#include <memory>
{{end}}

#include "flatbuffers/flatbuffers.h"
#include "objectbox.h"
#include "objectbox.hpp"
{{range $entity := .Model.EntitiesWithMeta}}
{{$entity.Meta.PreDeclareCppRelTargets -}}
{{with $entity.Meta.CppNamespaceStart}}
{{.}}{{end}}
struct {{$entity.Meta.CppName}}_;

{{PrintComments 0 $entity.Comments}}struct {{$entity.Meta.CppName}} {
	{{- range $property := $entity.Properties}}
	{{PrintComments 1 $property.Comments}}{{$property.Meta.CppTypeWithOptional}} {{$property.Meta.CppName}};
	{{- end}}

    struct _OBX_MetaInfo {
		static constexpr obx_schema_id entityId() { return {{$entity.Id.GetId}}; }
	
		static void setObjectId({{$entity.Meta.CppName}}& object, obx_id newId) { object.{{$entity.IdProperty.Meta.CppName}} = newId; }
	
		/// Write given object to the FlatBufferBuilder
		static void toFlatBuffer(flatbuffers::FlatBufferBuilder& fbb, const {{$entity.Meta.CppName}}& object);
	
		/// Read an object from a valid FlatBuffer
		static {{$entity.Meta.CppName}} fromFlatBuffer(const void* data, size_t size);
	
		/// Read an object from a valid FlatBuffer
		static std::unique_ptr<{{$entity.Meta.CppName}}> newFromFlatBuffer(const void* data, size_t size);
	
		/// Read an object from a valid FlatBuffer
		static void fromFlatBuffer(const void* data, size_t size, {{$entity.Meta.CppName}}& outObject);
	};
};

struct {{$entity.Meta.CppName}}_ {
{{- range $property := $entity.Properties}}
	static const 
	{{- if $property.RelationTarget}} obx::RelationProperty<{{$entity.Meta.CppName}}, {{$property.Meta.CppNameRelationTarget}}>
	{{- else}} obx::Property<{{$entity.Meta.CppName}}, OBXPropertyType_{{PropTypeName $property.Type}}>
	{{- end}} {{$property.Meta.CppName}};
{{- end}}
{{- range $relation := $entity.Relations}}
	static const obx::RelationStandalone<{{$entity.Meta.CppName}}, {{$relation.Target.Meta.CppName}}> {{$relation.Meta.CppName}};
{{- end}}
};
{{with $entity.Meta.CppNamespaceEnd}}{{.}}{{end -}}
{{end}}
`))
