// Copyright 2017 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

package prog

import (
	"fmt"
)

func (target *Target) generateSize(arg Arg, lenType *LenType) uint64 {
	if arg == nil {
		// Arg is an optional pointer, set size to 0.
		return 0
	}

	byteSize := lenType.ByteSize
	if byteSize == 0 {
		byteSize = 1
	}
	switch arg.Type().(type) {
	case *VmaType:
		a := arg.(*PointerArg)
		return a.PagesNum * target.PageSize / byteSize
	case *ArrayType:
		a := arg.(*GroupArg)
		if lenType.ByteSize != 0 {
			return a.Size() / byteSize
		} else {
			return uint64(len(a.Inner))
		}
	default:
		return arg.Size() / byteSize
	}
}

func (target *Target) assignSizes(args []Arg, parentsMap map[Arg]Arg) {
	// Create a map from field names to args.
	argsMap := make(map[string]Arg)
	for _, arg := range args {
		if IsPad(arg.Type()) {
			continue
		}
		argsMap[arg.Type().FieldName()] = arg
	}

	// Fill in size arguments.
	for _, arg := range args {
		if arg = InnerArg(arg); arg == nil {
			continue // Pointer to optional len field, no need to fill in value.
		}
		if typ, ok := arg.Type().(*LenType); ok {
			a := arg.(*ConstArg)

			buf, ok := argsMap[typ.Buf]
			if ok {
				a.Val = target.generateSize(InnerArg(buf), typ)
				continue
			}

			if typ.Buf == "parent" {
				a.Val = parentsMap[arg].Size()
				if typ.ByteSize != 0 {
					a.Val /= typ.ByteSize
				}
				continue
			}

			sizeAssigned := false
			for parent := parentsMap[arg]; parent != nil; parent = parentsMap[parent] {
				if typ.Buf == parent.Type().Name() {
					a.Val = parent.Size()
					if typ.ByteSize != 0 {
						a.Val /= typ.ByteSize
					}
					sizeAssigned = true
					break
				}
			}
			if sizeAssigned {
				continue
			}

			panic(fmt.Sprintf("len field '%v' references non existent field '%v', argsMap: %+v",
				typ.FieldName(), typ.Buf, argsMap))
		}
	}
}

func (target *Target) assignSizesArray(args []Arg) {
	parentsMap := make(map[Arg]Arg)
	foreachArgArray(&args, nil, func(arg, base Arg, _ *[]Arg) {
		if _, ok := arg.Type().(*StructType); ok {
			for _, field := range arg.(*GroupArg).Inner {
				parentsMap[InnerArg(field)] = arg
			}
		}
	})
	target.assignSizes(args, parentsMap)
	foreachArgArray(&args, nil, func(arg, base Arg, _ *[]Arg) {
		if _, ok := arg.Type().(*StructType); ok {
			target.assignSizes(arg.(*GroupArg).Inner, parentsMap)
		}
	})
}

func (target *Target) assignSizesCall(c *Call) {
	target.assignSizesArray(c.Args)
}
