/*
Code generated by github-terraform-generator; DO NOT EDIT.
Any modifications will be overwritten
*/

package tests

import (
	"context"
	"fmt"
	structs "github.com/Lenstra/terraform-plugin-generator/tests/structs"
	diag "github.com/hashicorp/terraform-plugin-framework/diag"
	path "github.com/hashicorp/terraform-plugin-framework/path"
)

type Getter interface {
	Get(context.Context, interface{}) diag.Diagnostics
}

func Decode[Target **structs.Coffee | **structs.Config | **structs.Ingredient](ctx context.Context, getter Getter, obj Target) diag.Diagnostics {
	switch o := any(obj).(type) {
	case **structs.Coffee:
		return DecodeCoffee(ctx, getter, o)
	case **structs.Config:
		return DecodeConfig(ctx, getter, o)
	case **structs.Ingredient:
		return DecodeIngredient(ctx, getter, o)
	default:
		var diags diag.Diagnostics
		diags.AddError("unsupported object type", fmt.Sprintf("%T is not supported in %s.Set(). Please report this issue to the provider developers.", obj, "tests"))
		return diags
	}
}

func DecodeCoffee(ctx context.Context, getter Getter, coffee **structs.Coffee) diag.Diagnostics {
	var data *Coffee
	diags := getter.Get(ctx, &data)
	if diags.HasError() {
		return diags
	}

	diags.Append(decodeCoffee(path.Empty(), data, coffee)...)
	return diags
}

func DecodeConfig(ctx context.Context, getter Getter, config **structs.Config) diag.Diagnostics {
	var data *Config
	diags := getter.Get(ctx, &data)
	if diags.HasError() {
		return diags
	}

	diags.Append(decodeConfig(path.Empty(), data, config)...)
	return diags
}

func DecodeIngredient(ctx context.Context, getter Getter, ingredient **structs.Ingredient) diag.Diagnostics {
	var data *Ingredient
	diags := getter.Get(ctx, &data)
	if diags.HasError() {
		return diags
	}

	diags.Append(decodeIngredient(path.Empty(), data, ingredient)...)
	return diags
}

func decodeCoffee(path path.Path, data *Coffee, coffee **structs.Coffee) (diags diag.Diagnostics) {
	if data == nil {
		return nil
	}

	target := &structs.Coffee{}
	if *coffee == nil {
		*coffee = target
	} else {
		target = *coffee
	}

	if !data.ID.IsNull() {
		n := int(data.ID.ValueInt64())
		target.ID = n
	}

	if !data.Name.IsNull() {
		target.Name = data.Name.ValueString()
	}

	if !data.Teaser.IsNull() {
		target.Teaser = data.Teaser.ValueString()
	}

	if !data.Description.IsNull() {
		target.Description = data.Description.ValueString()
	}

	if !data.Image.IsNull() {
		target.Image = data.Image.ValueString()
	}

	if data.Ingredients != nil {
		target.Ingredients = make([]structs.Ingredient, len(data.Ingredients))
		for i, data := range data.Ingredients {
			if data != nil {
				var item *structs.Ingredient
				diags.Append(decodeIngredient(path.AtName("ingredients").AtListIndex(i), data, &item)...)

				if diags.HasError() {
					return diags
				}

				target.Ingredients[i] = *item
			}
		}
	}

	if data.Customer != nil {
		var item *structs.Customer
		diags.Append(decodeCustomer(path.AtName("customer"), data.Customer, &item)...)

		if diags.HasError() {
			return diags
		}

		target.Customer = item
	}

	return diags
}

func decodeConfig(path path.Path, data *Config, config **structs.Config) (diags diag.Diagnostics) {
	if data == nil {
		return nil
	}

	target := &structs.Config{}
	if *config == nil {
		*config = target
	} else {
		target = *config
	}

	if !data.Host.IsNull() {
		target.Host = data.Host.ValueString()
	}

	if !data.Bool.IsNull() {
		target.PromotedBool.Bool = data.Bool.ValueBool()
	}

	if !data.Int.IsNull() {
		n := int(data.Int.ValueInt64())
		target.PromotedInt.Int = n
	}

	if !data.String.IsNull() {
		target.PromotedString.String = data.String.ValueString()
	}

	return diags
}

func decodeIngredient(path path.Path, data *Ingredient, ingredient **structs.Ingredient) (diags diag.Diagnostics) {
	if data == nil {
		return nil
	}

	target := &structs.Ingredient{}
	if *ingredient == nil {
		*ingredient = target
	} else {
		target = *ingredient
	}

	if !data.ID.IsNull() {
		n := int(data.ID.ValueInt64())
		target.ID = n
	}

	if !data.Float32.IsNull() {
		n := float32(data.Float32.ValueFloat64())
		target.Float32 = n
	}

	if !data.Float64.IsNull() {
		n := data.Float64.ValueFloat64()
		target.Float64 = n
	}

	return diags
}

func decodeCustomer(path path.Path, data *Customer, customer **structs.Customer) (diags diag.Diagnostics) {
	if data == nil {
		return nil
	}

	target := &structs.Customer{}
	if *customer == nil {
		*customer = target
	} else {
		target = *customer
	}

	if !data.ID.IsNull() {
		n := data.ID.ValueInt64()
		target.ID = n
	}

	if !data.Name.IsNull() {
		target.Name = data.Name.ValueString()
	}

	return diags
}
