package main

import "strings"

// Preset is a set of rules iperative to XXX_templates/ json files.
// They are used to manually set some properties of the generator.
// NOTE: Some strings are preocessed by regexp library, so you can use go-compatible regular expressions.
// NOTE: remember, that e.g. pattern "foo" will match "bazfoobar", so you should use "^foo$" to match only "foo".
type Preset struct {
	// ReverseMode if set, Skip* behavior is reversed.
	// Example: If SkipFuncs has "foo", and ReverseMode is set, only the "foo" function will be generateed.
	ReverseMode bool
	// SkipFuncs functions (from definitions.json) to be skipped
	// e.g. they are temporarily hard-coded
	// NOTE: These strings are parsed by regexp library.
	SkipFuncs []CIdentifier
	// SkipStructs allows to specify struct names that will be skipped.
	// NOTE: These strings are parsed by regexp library.
	SkipStructs []CIdentifier
	// SkipMethods struct names from structs_and_enums.json.
	// structures that's METHODS should be skipped
	// NOTE: These strings are parsed by regexp library.
	SkipMethods []CIdentifier
	// SkipTypedefs typedefs from typedefs_dict.json to be skipped
	// e.g. for hardcoded typedefs or typedefs which are obvious (e.g. ImU16 becomes uint16 without extra type information)
	// NOTE: These strings are parsed by regexp library.
	SkipTypedefs []CIdentifier
	// SkipFiles contains filenames (probably without extension) refering to location field in definitions.json.
	// This could aso contain line number in form of filename:lineN.
	// NOTE: These strings are parsed by regexp library.
	SkipFiles []string
	// TypedefsPoolSize sets a default size for callbacks pool.
	// Rembmber to set this as it defaults to 0 and you'll get no callbacks!
	TypedefsPoolSize int
	// TypedefsCustomPoolSizes allows to override TypedefsPoolSize for certain types.
	TypedefsCustomPoolSizes map[CIdentifier]int
	// Replace is a map for C -> Go names conversion.
	// It allows you to force-rename anything (including functions and enums)
	// With Replace all further processing will be skipped (prefix, e.t.c.)
	Replace map[CIdentifier]GoIdentifier
	// TrimPrefix allows to remove unwanted prefixes from everything during C->Go renaming.
	// NOTE: order sensitive!
	// NOTE: Case sensitive
	TrimPrefix []string
	// OriginReplace allows to force-replace function name with some other name.
	// Introduced to replace TextEditor_GetText -> TextEditor_GetText_alloc
	// but could be re-used to force use of another function than json tells us to use.
	//
	// It differs from Replace - Replace renames an identifier in general (changes its name but refers to the same function).
	// This allows to absolutely abandon the source C function and use some OTHER C function.
	OriginReplace map[CIdentifier]CIdentifier
	// DefaultArgReplace is used in C-side default args generation (gencpp.go).
	// cimgui-go uses this to change FLT_MIN with igGet_FLT_MIN()
	// NOTE: Iterated randomly!
	DefaultArgReplace map[CIdentifier]CIdentifier
	// DefaultArgArbitraryValue is similar to the above DefaultArgReplace, but
	// associates default arg name with any arbitrary value.
	// cimgui-go uses this to set text_end to 0
	DefaultArgArbitraryValue map[CIdentifier]CIdentifier
	// ExtraCGOPreamble allows to specify additional C code elements in Go files.
	// For example could be used to Include extra files.
	// For ease of use, its in form of []string. These lines will be merged and prefixed (if appliable) with '//'
	ExtraCGOPreamble []string
	// InternalFiles allows to specify files that are considered Internal.
	// If an identifier is found in such a file, it will be generated but its
	// name will be prefixed with InternalPrefix
	InternalFiles []string
	// InternalPrefix is a prefix for identifiers from InternalFiles.
	InternalPrefix string
	// PackagePath is an import path of the package.
	// This is base path. flags.PackageName will be added.
	// Example:
	//   "github.com/AllenDang/cimgui-go"
	//   If enerated with -pkg imgui, import path
	//   is supposed to be "github.com/AllenDang/cimgui-go/imgui"
	PackagePath string
	// SimpleTypes are used for simple (go-convertable) custom types (wrappers will be generated by simpleW/simpleR).
	// Example:
	//   ImS16 is defined as short in C code, so Go can easily convert it via int16()
	// Expected format is:
	//   "ImS16": ["int16", "C.ImS16", "pkgname"]
	// where:
	// - ImS16 is a C type name
	// - int16 is a Go-friendly type name
	// - C.ImS16 is a cgo compatible type name
	// - pkgname is a source package for the type (in this case int16 is a builtin so it should be empty)
	// See also: simpleW
	SimpleTypes map[CIdentifier][3]GoIdentifier
	// SimplePtrTypes are just like SimpleTypes but for pointer types.
	// Example:
	//   "ImS16": ["int16", "C.ImS16", "pkgname"]
	SimplePtrTypes map[CIdentifier][3]GoIdentifier
	// WrappableTypes are types that implement a special interface
	// github.com/AllenDang/cimgui-go/internal.WrappableType[CTYPE, SELF]
	// In short they are supposed to have 2 methods:
	// - ToC() CTYPE which returns SELF converted to CTYPE
	// - FromC(CTYPE) SELF which restores SELF from CTYPE.
	//
	// Key is a C type name, value is a list:
	// - Go name
	// - C name
	// - package where the type is defined
	// Example syntax:
	//    "ImVec2": ["Vec2", "C.ImVec2", "imgui"]
	WrappableTypes map[CIdentifier][3]GoIdentifier
	// CustomFinalizer is a map of C func name : C func name.
	// Assume:
	//   * F is a C function
	//   * F has EXACTLY 1 return value.
	// Then:
	//   * if FX = CustomFinalizer[F]
	//   * Every call to x = F(...) will have its respective call to FX(x)
	// NOTE: This FX call will be called before or just after returning x converted to Go-compatible type.
	// so for example:
	//   x := F(x)
	//   defer FX(x)
	//   return CToGo(x)
	// In other words, CToGo is supposed to copy the value of x.
	CustomFInalizer map[CIdentifier]CIdentifier
}

func (p *Preset) MergeCGoPreamble() string {
	result := ""
	for _, line := range p.ExtraCGOPreamble {
		result += "// " + line + "\n"
	}

	result = strings.TrimSuffix(result, "\n")

	return result
}
