// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package fidlgen_cpp

import (
	"go.fuchsia.dev/fuchsia/tools/fidl/lib/fidlgen"
)

type Union struct {
	Attributes
	fidlgen.Strictness
	fidlgen.Resourceness
	nameVariants
	CodingTableType    string
	TagEnum            nameVariants
	TagUnknown         nameVariants
	TagInvalid         nameVariants
	WireOrdinalEnum    name
	WireInvalidOrdinal name
	Members            []UnionMember
	InlineSize         int
	MaxHandles         int
	MaxOutOfLine       int
	Result             *Result
	HasPointer         bool
}

func (Union) Kind() declKind {
	return Kinds.Union
}

var _ Kinded = (*Union)(nil)
var _ namespaced = (*Union)(nil)

type UnionMember struct {
	Attributes
	nameVariants
	Ordinal           uint64
	Type              Type
	StorageName       name
	TagName           nameVariants
	WireOrdinalName   name
	Offset            int
	HandleInformation *HandleInformation
}

func (um UnionMember) UpperCamelCaseName() string {
	return fidlgen.ToUpperCamelCase(um.Name())
}

func (um UnionMember) NameAndType() (string, Type) {
	return um.Name(), um.Type
}
func (c *compiler) compileUnion(val fidlgen.Union) Union {
	name := c.compileNameVariants(val.Name)
	codingTableType := c.compileCodingTableType(val.Name)
	tagEnum := name.nest("Tag")
	wireOrdinalEnum := name.Wire.nest("Ordinal")
	u := Union{
		Attributes:         Attributes{val.Attributes},
		Strictness:         val.Strictness,
		Resourceness:       val.Resourceness,
		nameVariants:       name,
		CodingTableType:    codingTableType,
		TagEnum:            tagEnum,
		TagUnknown:         tagEnum.nest("kUnknown"),
		TagInvalid:         tagEnum.nest("Invalid"),
		WireOrdinalEnum:    wireOrdinalEnum,
		WireInvalidOrdinal: wireOrdinalEnum.nest("Invalid"),
		InlineSize:         val.TypeShapeV1.InlineSize,
		MaxHandles:         val.TypeShapeV1.MaxHandles,
		MaxOutOfLine:       val.TypeShapeV1.MaxOutOfLine,
		HasPointer:         val.TypeShapeV1.Depth > 0,
	}

	for _, mem := range val.Members {
		if mem.Reserved {
			continue
		}
		name := unionMemberContext.transform(mem.Name)
		tag := unionMemberTagContext.transform(mem.Name)
		u.Members = append(u.Members, UnionMember{
			Attributes:        Attributes{mem.Attributes},
			Ordinal:           uint64(mem.Ordinal),
			Type:              c.compileType(mem.Type),
			nameVariants:      name,
			StorageName:       name.appendName("_").Natural,
			TagName:           u.TagEnum.nestVariants(tag),
			WireOrdinalName:   u.WireOrdinalEnum.nest(tag.Wire.Name()),
			Offset:            mem.Offset,
			HandleInformation: c.fieldHandleInformation(&mem.Type),
		})
	}

	if val.MethodResult != nil {
		result := Result{
			ResultDecl:      u.nameVariants,
			ValueStructDecl: u.Members[0].Type.nameVariants,
			ErrorDecl:       u.Members[1].Type.nameVariants,
		}
		c.resultForStruct[val.MethodResult.ValueType.Identifier] = &result
		c.resultForUnion[val.Name] = &result
		u.Result = &result
	}

	return u
}
