// 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"
)

// We need to support structs as resources,
// but for now we just special-case timespec/timeval.
var timespecRes = &ResourceDesc{
	Name: "timespec",
	Kind: []string{"timespec"},
}

func (target *Target) calcResourceCtors(kind []string, precise bool) []*Syscall {
	// Find calls that produce the necessary resources.
	var metas []*Syscall
	for _, meta := range target.Syscalls {
		// Recurse into arguments to see if there is an out/inout arg of necessary type.
		ok := false
		ForeachType(meta, func(typ Type) {
			if ok {
				return
			}
			switch typ1 := typ.(type) {
			case *ResourceType:
				if typ1.Dir() != DirIn && isCompatibleResourceImpl(kind, typ1.Desc.Kind, precise) {
					ok = true
				}
			}
		})
		if ok {
			metas = append(metas, meta)
		}
	}
	if kind[0] == timespecRes.Name {
		if c := target.SyscallMap["clock_gettime"]; c != nil {
			metas = append(metas, c)
		}
	}
	return metas
}

// isCompatibleResource returns true if resource of kind src can be passed as an argument of kind dst.
func (target *Target) isCompatibleResource(dst, src string) bool {
	if dst == target.any.res16.TypeName ||
		dst == target.any.res32.TypeName ||
		dst == target.any.res64.TypeName ||
		dst == target.any.resdec.TypeName ||
		dst == target.any.reshex.TypeName ||
		dst == target.any.resoct.TypeName {
		return true
	}
	dstRes := target.resourceMap[dst]
	if dstRes == nil {
		panic(fmt.Sprintf("unknown resource '%v'", dst))
	}
	srcRes := target.resourceMap[src]
	if srcRes == nil {
		panic(fmt.Sprintf("unknown resource '%v'", src))
	}
	return isCompatibleResourceImpl(dstRes.Kind, srcRes.Kind, false)
}

// isCompatibleResourceImpl returns true if resource of kind src can be passed as an argument of kind dst.
// If precise is true, then it does not allow passing a less specialized resource (e.g. fd)
// as a more specialized resource (e.g. socket). Otherwise it does.
func isCompatibleResourceImpl(dst, src []string, precise bool) bool {
	if len(dst) > len(src) {
		// dst is more specialized, e.g dst=socket, src=fd.
		if precise {
			return false
		}
		dst = dst[:len(src)]
	}
	if len(src) > len(dst) {
		// src is more specialized, e.g dst=fd, src=socket.
		src = src[:len(dst)]
	}
	for i, k := range dst {
		if k != src[i] {
			return false
		}
	}
	return true
}

func (target *Target) inputResources(c *Syscall) []*ResourceDesc {
	var resources []*ResourceDesc
	ForeachType(c, func(typ Type) {
		if typ.Dir() == DirOut {
			return
		}
		switch typ1 := typ.(type) {
		case *ResourceType:
			if !typ1.IsOptional {
				resources = append(resources, typ1.Desc)
			}
		case *StructType:
			if target.OS == "linux" && (typ1.Name() == "timespec" || typ1.Name() == "timeval") {
				resources = append(resources, timespecRes)
			}
		}
	})
	return resources
}

func (target *Target) outputResources(c *Syscall) []*ResourceDesc {
	var resources []*ResourceDesc
	ForeachType(c, func(typ Type) {
		switch typ1 := typ.(type) {
		case *ResourceType:
			if typ1.Dir() != DirIn {
				resources = append(resources, typ1.Desc)
			}
		}
	})
	if c.CallName == "clock_gettime" {
		resources = append(resources, timespecRes)
	}
	return resources
}

func (target *Target) TransitivelyEnabledCalls(enabled map[*Syscall]bool) (map[*Syscall]bool, map[*Syscall]string) {
	supported := make(map[*Syscall]bool)
	disabled := make(map[*Syscall]string)
	canCreate := make(map[string]bool)
	inputResources := make(map[*Syscall][]*ResourceDesc)
	for c := range enabled {
		inputResources[c] = target.inputResources(c)

		if c.Name == "pipe$9p" {
			fmt.Printf("%v: input resource: %+v\n", c.Name, inputResources[c])
		}
	}
	for {
		n := len(supported)
		for c := range enabled {
			if supported[c] {
				continue
			}
			ready := true
			for _, res := range inputResources[c] {
				if !canCreate[res.Name] {
					ready = false
					break
				}
			}
			if ready {
				supported[c] = true
				for _, res := range target.outputResources(c) {
					for _, kind := range res.Kind {
						canCreate[kind] = true
					}
				}
			}
		}
		if n == len(supported) {
			break
		}
	}
	ctors := make(map[string][]string)
	for c := range enabled {
		if supported[c] {
			continue
		}
		for _, res := range inputResources[c] {
			if canCreate[res.Name] {
				continue
			}
			if ctors[res.Name] == nil {
				var names []string
				for _, call := range target.calcResourceCtors(res.Kind, true) {
					names = append(names, call.Name)
				}
				ctors[res.Name] = names
			}
			disabled[c] = fmt.Sprintf("no syscalls can create resource %v,"+
				" enable some syscalls that can create it %v",
				res.Name, ctors[res.Name])
			break
		}
	}
	if len(enabled) != len(supported)+len(disabled) {
		panic("lost syscalls")
	}
	return supported, disabled
}
