// Copyright 2017 The Go 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 render

import (
	"bytes"
	"fmt"
	"go/ast"
	"go/format"
	"go/token"
	"strings"
)

const dotDotDot = "..."

// OneLineNodeDepth returns a one-line summary of the given input node.
// The depth specifies the current depth when traversing the AST and the
// function will stop traversing once depth reaches maxSynopsisNodeDepth.
func OneLineNodeDepth(fset *token.FileSet, node ast.Node, depth int) string {
	if depth == maxSynopsisNodeDepth {
		return dotDotDot
	}
	depth++

	switch n := node.(type) {
	case nil:
		return ""

	case *ast.GenDecl:
		trailer := ""
		if len(n.Specs) > 1 {
			trailer = " " + dotDotDot
		}

		switch n.Tok {
		case token.CONST, token.VAR:
			for i, spec := range n.Specs {
				valueSpec := spec.(*ast.ValueSpec) // must succeed; we can't mix types in one GenDecl.
				return ConstOrVarSynopsis(valueSpec, fset, n.Tok, trailer, i, depth)
			}
		case token.TYPE:
			if len(n.Specs) > 0 {
				return OneLineNodeDepth(fset, n.Specs[0], depth) + trailer
			}
		case token.IMPORT:
			if len(n.Specs) > 0 {
				pkg := n.Specs[0].(*ast.ImportSpec).Path.Value
				return fmt.Sprintf("%s %s%s", n.Tok, pkg, trailer)
			}
		}
		return fmt.Sprintf("%s ()", n.Tok)

	case *ast.FuncDecl:
		// Formats func declarations.
		name := n.Name.Name
		recv := OneLineNodeDepth(fset, n.Recv, depth)
		if len(recv) > 0 {
			recv = "(" + recv + ") "
		}
		fnc := OneLineNodeDepth(fset, n.Type, depth)
		if strings.Index(fnc, "func") == 0 {
			fnc = fnc[4:]
		}
		return fmt.Sprintf("func %s%s%s", recv, name, fnc)

	case *ast.TypeSpec:
		sep := " "
		if n.Assign.IsValid() {
			sep = " = "
		}
		return fmt.Sprintf("type %s%s%s", n.Name.Name, sep, OneLineNodeDepth(fset, n.Type, depth))

	case *ast.FuncType:
		var params []string
		if n.Params != nil {
			for _, field := range n.Params.List {
				params = append(params, OneLineField(fset, field, depth))
			}
		}
		needParens := false
		var results []string
		if n.Results != nil {
			needParens = needParens || len(n.Results.List) > 1
			for _, field := range n.Results.List {
				needParens = needParens || len(field.Names) > 0
				results = append(results, OneLineField(fset, field, depth))
			}
		}

		param := joinStrings(params)
		if len(results) == 0 {
			return fmt.Sprintf("func(%s)", param)
		}
		result := joinStrings(results)
		if !needParens {
			return fmt.Sprintf("func(%s) %s", param, result)
		}
		return fmt.Sprintf("func(%s) (%s)", param, result)

	case *ast.StructType:
		if n.Fields == nil || len(n.Fields.List) == 0 {
			return "struct{}"
		}
		return "struct{ ... }"

	case *ast.InterfaceType:
		if n.Methods == nil || len(n.Methods.List) == 0 {
			return "interface{}"
		}
		return "interface{ ... }"

	case *ast.FieldList:
		if n == nil || len(n.List) == 0 {
			return ""
		}
		if len(n.List) == 1 {
			return OneLineField(fset, n.List[0], depth)
		}
		return dotDotDot

	case *ast.FuncLit:
		return OneLineNodeDepth(fset, n.Type, depth) + " { ... }"

	case *ast.CompositeLit:
		typ := OneLineNodeDepth(fset, n.Type, depth)
		if len(n.Elts) == 0 {
			return fmt.Sprintf("%s{}", typ)
		}
		return fmt.Sprintf("%s{ %s }", typ, dotDotDot)

	case *ast.ArrayType:
		length := OneLineNodeDepth(fset, n.Len, depth)
		element := OneLineNodeDepth(fset, n.Elt, depth)
		return fmt.Sprintf("[%s]%s", length, element)

	case *ast.MapType:
		key := OneLineNodeDepth(fset, n.Key, depth)
		value := OneLineNodeDepth(fset, n.Value, depth)
		return fmt.Sprintf("map[%s]%s", key, value)

	case *ast.CallExpr:
		fnc := OneLineNodeDepth(fset, n.Fun, depth)
		var args []string
		for _, arg := range n.Args {
			args = append(args, OneLineNodeDepth(fset, arg, depth))
		}
		return fmt.Sprintf("%s(%s)", fnc, joinStrings(args))

	case *ast.UnaryExpr:
		return fmt.Sprintf("%s%s", n.Op, OneLineNodeDepth(fset, n.X, depth))

	case *ast.Ident:
		return n.Name

	default:
		// As a fallback, use default formatter for all unknown node types.
		buf := new(bytes.Buffer)
		format.Node(buf, fset, node)
		s := buf.String()
		if strings.Contains(s, "\n") {
			return dotDotDot
		}
		return s
	}
}

func ConstOrVarSynopsis(valueSpec *ast.ValueSpec, fset *token.FileSet, tok token.Token,
	trailer string, i, depth int) string {
	if len(valueSpec.Names) > 1 || len(valueSpec.Values) > 1 {
		trailer = " " + dotDotDot
	}

	// The type name may carry over from a previous specification in the
	// case of constants and iota.
	typ := ""
	if valueSpec.Type != nil {
		typ = fmt.Sprintf(" %s", OneLineNodeDepth(fset, valueSpec.Type, depth))
	} else if len(valueSpec.Values) > 0 {
		typ = ""
	}

	val := ""
	if i < len(valueSpec.Values) && valueSpec.Values[i] != nil {
		val = fmt.Sprintf(" = %s", OneLineNodeDepth(fset, valueSpec.Values[i], depth))
	}
	return fmt.Sprintf("%s %s%s%s%s", tok, valueSpec.Names[0], typ, val, trailer)
}

// OneLineField returns a one-line summary of the field.
func OneLineField(fset *token.FileSet, field *ast.Field, depth int) string {
	var names []string
	for _, name := range field.Names {
		names = append(names, name.Name)
	}
	if len(names) == 0 {
		return OneLineNodeDepth(fset, field.Type, depth)
	}
	return joinStrings(names) + " " + OneLineNodeDepth(fset, field.Type, depth)
}

// joinStrings formats the input as a comma-separated list,
// but truncates the list at some reasonable length if necessary.
func joinStrings(ss []string) string {
	const widthLimit = 80
	var n int
	for i, s := range ss {
		n += len(s) + len(", ")
		if n > widthLimit {
			ss = append(ss[:i:i], "...")
			break
		}
	}
	return strings.Join(ss, ", ")
}
