#ifndef BROLANG_NATIVE_H
#define BROLANG_NATIVE_H

#include <child.h>
#include "repeat.h"
#undef IMPORTED_REPEAT
#include "repeat.h"
#include "guarded.h"
#undef IMPORTED_GUARDED
#include "guarded.h"
#include "once.h"
#undef IMPORTED_ONCE
#include "once.h"

typedef int imported_int;
typedef imported_int imported_int_alias;
typedef struct Imported_Handle Imported_Handle;
typedef void (*Imported_Callback)(int value);
typedef int (*Imported_Mapper)(int value);
typedef struct Imported_Value {
	int value;
} Imported_Value;
typedef struct Imported_Color {
	unsigned char r;
	unsigned char g;
	unsigned char b;
	unsigned char a;
} Imported_Color;
typedef struct Imported_Zero_Inner {
	float weight;
	int values[2];
	const char *label;
} Imported_Zero_Inner;
typedef union Imported_Zero_Union {
	int integer;
	double decimal;
} Imported_Zero_Union;
typedef struct Imported_Zero_Outer {
	int head;
	Imported_Zero_Inner inner;
	Imported_Zero_Union choice;
} Imported_Zero_Outer;
typedef struct Imported_Array_Record {
	int values[2];
} Imported_Array_Record;
typedef struct Imported_Conversions {
	unsigned char wrapped;
	int truncated;
	float from_integer;
	double from_float;
	const char *pointer;
} Imported_Conversions;
typedef struct Imported_Signed_Narrow {
	signed char value;
} Imported_Signed_Narrow;
typedef union Imported_Union {
	int value;
} Imported_Union;
typedef int Imported_Const_Array[2];
typedef struct Imported_Bitfield {
	unsigned value : 1;
} Imported_Bitfield;
typedef struct __attribute__((packed)) Imported_Packed {
	char first;
	int second;
} Imported_Packed;
typedef struct Imported_Flexible {
	int count;
	int values[];
} Imported_Flexible;
typedef struct Imported_Qualified {
	const int value;
} Imported_Qualified;
typedef struct Imported_Overaligned {
	_Alignas(16) int value;
} Imported_Overaligned;
typedef struct Imported_Anonymous {
	struct {
		int value;
	};
} Imported_Anonymous;
typedef enum Imported_Enum {
	IMPORTED_ENUM_NEGATIVE = -2,
	IMPORTED_ENUM_SAME = -2,
	IMPORTED_ENUM_VALUE = 7,
	IMPORTED_ENUM_BACK = 3,
} Imported_Enum;
enum {
	IMPORTED_ANON_ENUM = 9,
};
typedef struct Imported_Enum_Record {
	Imported_Enum value;
} Imported_Enum_Record;
typedef Imported_Enum (*Imported_Enum_Callback)(Imported_Enum value);

int imported_add(imported_int_alias left, int right);
unsigned long imported_scalar(unsigned char value, unsigned long extra);
Imported_Handle *imported_handle(void);
int imported_read(const Imported_Handle *handle);
int imported_string(const char *value);
int imported_apply(Imported_Mapper mapper, int value);
int imported_enum_check(Imported_Enum first, Imported_Enum second);
int imported_enum_variadic(int expected, ...);
Imported_Enum_Record imported_enum_record(Imported_Enum_Record value);
Imported_Enum imported_enum_apply(Imported_Enum_Callback callback, Imported_Enum value);
Imported_Value imported_by_value(Imported_Value value);
int imported_check_state(
	Imported_Color color,
	int macro_value,
	int const_value,
	int global_value,
	int record_value,
	int octal_value,
	unsigned int uint_value,
	int redefined_value,
	int inactive_undef_value,
	int repeated_value,
	unsigned int hex_e_value,
	long negative_decimal_value,
	unsigned int negative_hex_value,
	unsigned int negative_uint_value,
	float float_value,
	double double_value
);
int imported_check_zero_state(
	Imported_Color partial,
	Imported_Zero_Outer nested,
	Imported_Zero_Union first_union
);
int imported_check_array_record(void);
int imported_check_conversions(Imported_Conversions value);
int imported_volatile(volatile int *value);
_Bool imported_bool(_Bool value);
extern int imported_global;
extern const int imported_const_global;
extern const int imported_const_array[2];
extern const Imported_Const_Array imported_typedef_const_array;
extern int imported_redeclared_array[];
extern int imported_redeclared_array[4];
extern Imported_Value imported_record_global;
extern const Imported_Array_Record imported_const_array_record;
extern Imported_Array_Record imported_mutable_array_record;
extern Imported_Enum imported_enum_global;
extern _Thread_local int imported_tls_global;
extern int IMPORTED_SHADOW_OBJECT;
int IMPORTED_SHADOW_FUNCTION(void);
extern int IMPORTED_SHADOW_UNSUPPORTED;
extern int IMPORTED_EMPTY_SHADOW;

#define CLITERAL(type) (type)
#define IMPORTED_SHADOW_OBJECT 71
#define IMPORTED_SHADOW_FUNCTION 72
#define IMPORTED_SHADOW_UNSUPPORTED (1 + 2)
#define IMPORTED_MAGIC 42
#define IMPORTED_COLOR CLITERAL(Imported_Color){ 255, 255, 255, 255 }
#define IMPORTED_PARTIAL_COLOR CLITERAL(Imported_Color){ 7 }
#define IMPORTED_ZERO_NESTED CLITERAL(Imported_Zero_Outer){ 5 }
#define IMPORTED_FIRST_UNION CLITERAL(Imported_Zero_Union){ 9 }
#define IMPORTED_CONVERSIONS CLITERAL(Imported_Conversions){ -1, 3.75, 42, 16777217.0f, 0 }
#define IMPORTED_SIGNED_NARROW_BAD CLITERAL(Imported_Signed_Narrow){ 128 }
#define IMPORTED_TOO_MANY_COLOR CLITERAL(Imported_Color){ 1, 2, 3, 4, 5 }
#define IMPORTED_BAD_EXPR (1 + 2)
#define IMPORTED_OCTAL 010
#define IMPORTED_UINT 4294967295U
#define IMPORTED_HEX_E 0xDEADBEEF
#define IMPORTED_NEG_DECIMAL -2147483648
#define IMPORTED_NEG_HEX -0x80000000
#define IMPORTED_NEG_UINT -1U
#define IMPORTED_FLOAT 2.5f
#define IMPORTED_DOUBLE 6.25
#define IMPORTED_FLOAT_OVERFLOW 1e40f
#define IMPORTED_EMPTY_SHADOW
#define IMPORTED_REDEFINED 1
#undef IMPORTED_REDEFINED
#define IMPORTED_REDEFINED 2
#define IMPORTED_GONE 3
#undef IMPORTED_GONE
#define IMPORTED_REDEFINED_BAD 1
#undef IMPORTED_REDEFINED_BAD
#define IMPORTED_REDEFINED_BAD (1 + 2)
#define IMPORTED_ACTIVE_AFTER_INACTIVE_UNDEF 77
#if 0
#undef IMPORTED_ACTIVE_AFTER_INACTIVE_UNDEF
#endif

static inline int imported_inline(int value) {
	return value + 1;
}

static inline Imported_Value imported_inline_record(Imported_Value value) {
	Imported_Value result = { value.value * 2 };
	return result;
}

static inline int imported_inline_bad_layout(Imported_Packed value) {
	return value.first;
}

static inline int imported_inline_variadic(int marker, ...) {
	return marker;
}

int imported_check_inline(int scalar, int record);

#ifdef BROLANG_FEATURE
int configured_value(int value);
#endif

#define IMPORTED_MACRO 42
int imported_variadic(int marker, ...);
Imported_Bitfield imported_bitfield(Imported_Bitfield value);
Imported_Packed imported_packed(Imported_Packed value);
Imported_Flexible imported_flexible(Imported_Flexible value);
Imported_Qualified imported_qualified(Imported_Qualified value);
Imported_Overaligned imported_overaligned(Imported_Overaligned value);
Imported_Anonymous imported_anonymous(Imported_Anonymous value);

#endif
