// Copyright 2022 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 (
	"fmt"
	"sort"
	"strings"

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

// DeclDepGraph represents the definitional dependency graph between
// declarations in a library.
//
// We do not create edges to nullable types. This makes it possible to write
// some recursive types in FIDL. However, we do not have comprehensive support
// for recursive types. See https://fxbug.dev/42110612 for details.
//
// Similarly, we do not create edges to protocols via endpoint dependencies, as
// that same protocol may freely appear in the response type of one its
// methods.
type DeclDepGraph struct {
	nodes declDepNodeMap
	decls map[fidlgen.EncodedCompoundIdentifier]fidlgen.Decl
}

type declDepNode struct {
	// The name of the associated declaration.
	name fidlgen.EncodedCompoundIdentifier

	// The reverse dependencies (i.e., dependents) of the associated
	// declaration. This is tracked to facilitate a topological sort with
	// respect to dependency.
	revDeps declDepNodeMap
}

type declDepNodeMap map[fidlgen.EncodedCompoundIdentifier]*declDepNode

// NewDeclDepGraph computes the dependency graph for a given library.
func NewDeclDepGraph(r fidlgen.Root) DeclDepGraph {
	g := DeclDepGraph{
		nodes: make(declDepNodeMap),
		decls: make(map[fidlgen.EncodedCompoundIdentifier]fidlgen.Decl),
	}
	r.ForEachDecl(func(decl fidlgen.Decl) { g.addDecl(decl) })
	return g
}

// SortedDecls returns a deterministic, topologically sorted list of the
// associated declarations, so that a declaration always appears before those
// that depend on it. Beyond preserving this relation, the list attempts to
// prioritize declarations in terms of their original ordering in source.
func (g *DeclDepGraph) SortedDecls() []fidlgen.Decl {
	const (
		nodeProccesing int = iota
		nodeProcessed
	)

	var decls []fidlgen.Decl
	nodeState := make(map[fidlgen.EncodedCompoundIdentifier]int)
	var visit func(*declDepNode, []string)
	visit = func(node *declDepNode, depChain []string) {
		depChain = append(depChain, string(node.name))
		if state, ok := nodeState[node.name]; ok {
			switch state {
			case nodeProccesing:
				panic(fmt.Sprintf("cyclic dependency: %s", strings.Join(depChain, " <- ")))
			case nodeProcessed:
				return
			}
		}

		nodeState[node.name] = nodeProccesing
		for _, dep := range g.normalizeNodes(node.revDeps) {
			visit(dep, depChain)
		}
		if decl, ok := g.decls[node.name]; ok {
			decls = append([]fidlgen.Decl{decl}, decls...)
		}
		nodeState[node.name] = nodeProcessed
		depChain = depChain[:len(depChain)-1]
	}

	for _, node := range g.normalizeNodes(g.nodes) {
		visit(node, nil)
	}
	return decls
}

// GetDirectDependents returns the declarations that are directly dependent on
// a given one, referenced by name. The returned declarations are given in
// source order (lexicographically first on filename). A boolean is also
// returned indicating whether the provided declaration is contained in the
// graph.
func (g DeclDepGraph) GetDirectDependents(name fidlgen.EncodedCompoundIdentifier) ([]fidlgen.Decl, bool) {
	// First check whether the provided name represents a local declaration.
	if _, ok := g.decls[name]; !ok {
		return nil, false
	}
	node, ok := g.nodes[name]
	if !ok {
		return nil, false
	}
	var decls []fidlgen.Decl
	for _, revDep := range node.revDeps {
		// All direct dependents on a local declaration should be local declarations themselves.
		decls = append(decls, g.decls[revDep.name])
	}
	sort.Slice(decls, func(i, j int) bool {
		return fidlgen.LocationCmp(decls[i].GetLocation(), decls[j].GetLocation())
	})
	return decls, true
}

// Since `map` access is randomized, a normalization of `declDepNodeMap`s is
// needed to produce a deterministic list. Topological sorting alone is
// insufficient, as there are many possible orderings that preserve that
// relation.
//
// To approximate the desired order described on SortedDecls(), we sort nodes
// with regards to the *opposite* of the following relations (opposite since we
// will be *prepending* items in this order during topological sorting):
//
// * If both nodes represent local (i.e., non-imported) declarations, source
// ordering is preserved (falling back to a lexicographic comparison on
// filenames if the two declarations came from different files).
//
// * If both nodes represent imported declarations, the one with the
// lexicographically smaller name is prioritized. (This is an arbitrary choice.)
//
// * If only one node of the two represents a local declaration, the local one
// is prioritized. (This is also an arbitrary choice.)
func (g DeclDepGraph) normalizeNodes(m declDepNodeMap) []*declDepNode {
	var nodes []*declDepNode
	for _, node := range m {
		nodes = append(nodes, node)
	}
	sort.Slice(nodes, func(i, j int) bool {
		iName := nodes[i].name
		jName := nodes[j].name
		iDecl, iLocal := g.decls[iName]
		jDecl, jLocal := g.decls[jName]
		if iLocal && jLocal {
			return !fidlgen.LocationCmp(iDecl.GetLocation(), jDecl.GetLocation())
		}
		if iLocal != jLocal {
			return iLocal
		}
		return strings.Compare(string(iName), string(jName)) > 0
	})
	return nodes
}

func (g *DeclDepGraph) addDecl(decl fidlgen.Decl) {
	node := g.getNode(decl.GetName())
	g.decls[node.name] = decl

	switch decl := decl.(type) {
	case *fidlgen.Const:
		g.addDepsFromType(node, decl.Type)
		g.addDepsFromConstant(node, decl.Value)
	case *fidlgen.Bits:
		g.addDepsFromType(node, decl.Type)
		for _, m := range decl.Members {
			g.addDepsFromConstant(node, m.Value)
		}
	case *fidlgen.Enum:
		for _, m := range decl.Members {
			g.addDepsFromConstant(node, m.Value)
		}
	case *fidlgen.Resource:
		for _, prop := range decl.Properties {
			g.addDepsFromType(node, prop.Type)
		}
	case *fidlgen.Protocol:
		for _, comp := range decl.Composed {
			g.addDep(node, comp.Name)
		}
		for _, m := range decl.Methods {
			if req, ok := m.GetRequestPayloadIdentifier(); ok {
				g.addDep(node, req)
			}
			if resp, ok := m.GetResponsePayloadIdentifier(); ok {
				g.addDep(node, resp)
			}
		}
	case *fidlgen.Service:
		for _, m := range decl.Members {
			g.addDepsFromType(node, m.Type)
		}
	case *fidlgen.Struct:
		for _, m := range decl.Members {
			g.addDepsFromType(node, m.Type)
			if m.MaybeDefaultValue != nil {
				g.addDepsFromConstant(node, *m.MaybeDefaultValue)
			}
			if m.MaybeFromAlias != nil {
				g.addDepsFromTypeCtor(node, *m.MaybeFromAlias)
			}
		}
	case *fidlgen.Table:
		for _, m := range decl.Members {
			g.addDepsFromType(node, m.Type)
			if m.MaybeFromAlias != nil {
				g.addDepsFromTypeCtor(node, *m.MaybeFromAlias)
			}
		}
	case *fidlgen.Union:
		for _, m := range decl.Members {
			g.addDepsFromType(node, m.Type)
			if m.MaybeFromAlias != nil {
				g.addDepsFromTypeCtor(node, *m.MaybeFromAlias)
			}
		}
	case *fidlgen.Alias:
		g.addDepsFromTypeCtor(node, decl.PartialTypeConstructor)
	case *fidlgen.NewType:
		if decl.Alias != nil {
			g.addDepsFromTypeCtor(node, *decl.Alias)
		} else {
			g.addDepsFromType(node, decl.Type)
		}
	case *fidlgen.Overlay:
		for _, m := range decl.Members {
			g.addDepsFromType(node, m.Type)
			if m.MaybeFromAlias != nil {
				g.addDepsFromTypeCtor(node, *m.MaybeFromAlias)
			}
		}
	}
}

func (g *DeclDepGraph) getNode(decl fidlgen.EncodedCompoundIdentifier) *declDepNode {
	node, ok := g.nodes[decl]
	if !ok {
		node = &declDepNode{
			name:    decl,
			revDeps: make(declDepNodeMap),
		}
		g.nodes[decl] = node
	}
	return node
}

func (g *DeclDepGraph) addDep(node *declDepNode, dep fidlgen.EncodedCompoundIdentifier) {
	g.getNode(dep).revDeps[node.name] = node
}

func (g *DeclDepGraph) addDepsFromConstant(node *declDepNode, c fidlgen.Constant) {
	if c.Kind == fidlgen.IdentifierConstant {
		g.addDep(node, c.Identifier)
	}
}

func (g *DeclDepGraph) addDepsFromType(node *declDepNode, typ fidlgen.Type) {
	// As above, we do not create edges to nullable types or protocols via
	// endpoint dependencies.
	if typ.Nullable || typ.Kind == fidlgen.EndpointType {
		return
	}

	switch typ.Kind {
	case fidlgen.ArrayType, fidlgen.VectorType:
		g.addDepsFromType(node, *typ.ElementType)
	case fidlgen.HandleType:
		// TODO(https://fxbug.dev/42156522): ResourceIdentifier should be an
		// `fidlgen.EncodedCompoundIdentifier`.
		g.addDep(node, fidlgen.EncodedCompoundIdentifier(typ.ResourceIdentifier))
	case fidlgen.IdentifierType:
		g.addDep(node, typ.Identifier)
	}
}

func (g *DeclDepGraph) addDepsFromTypeCtor(node *declDepNode, ctor fidlgen.PartialTypeConstructor) {
	// As above, we do not create edges to nullable types.
	if ctor.Nullable {
		return
	}
	if !ctor.Name.IsBuiltIn() {
		g.addDep(node, ctor.Name)
	}
	for _, arg := range ctor.Args {
		g.addDepsFromTypeCtor(node, arg)
	}
}
