// 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(res *ResourceDesc, precise bool) []*Syscall {
	var metas []*Syscall
	for _, ctor := range res.Ctors {
		if !precise || ctor.Precise {
			metas = append(metas, target.Syscalls[ctor.Call])
		}
	}
	if res.Kind[0] == timespecRes.Name {
		if c := target.SyscallMap["clock_gettime"]; c != nil {
			metas = append(metas, c)
		}
	}
	return metas
}

func (target *Target) populateResourceCtors() {
	// Find resources that are created by each call.
	callsResources := make([][]*ResourceDesc, len(target.Syscalls))
	for call, meta := range target.Syscalls {
		ForeachType(meta, func(typ Type) {
			switch typ1 := typ.(type) {
			case *ResourceType:
				if typ1.Dir() != DirIn {
					callsResources[call] = append(callsResources[call], typ1.Desc)
				}
			}
		})
	}

	// Populate resource ctors accounting for resource compatibility.
	for _, res := range target.Resources {
		for call, callResources := range callsResources {
			preciseOk := false
			impreciseOk := false
			for _, callRes := range callResources {
				if preciseOk && impreciseOk {
					break
				}
				if isCompatibleResourceImpl(res.Kind, callRes.Kind, true) {
					preciseOk = true
				}
				if isCompatibleResourceImpl(res.Kind, callRes.Kind, false) {
					impreciseOk = true
				}
			}
			if preciseOk {
				res.Ctors = append(res.Ctors, ResourceCtor{call, true})
			}
			if impreciseOk {
				res.Ctors = append(res.Ctors, ResourceCtor{call, false})
			}
		}
	}
}

// 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, 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
}
