// Copyright 2019 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 completion

import (
	"go/ast"

	"golang.org/x/tools/gopls/internal/lsp/safetoken"
	"golang.org/x/tools/gopls/internal/lsp/snippet"
)

// structFieldSnippet calculates the snippet for struct literal field names.
func (c *completer) structFieldSnippet(cand candidate, detail string, snip *snippet.Builder) {
	if !c.wantStructFieldCompletions() {
		return
	}

	// If we are in a deep completion then we can't be completing a field
	// name (e.g. "Foo{f<>}" completing to "Foo{f.Bar}" should not generate
	// a snippet).
	if len(cand.path) > 0 {
		return
	}

	clInfo := c.enclosingCompositeLiteral

	// If we are already in a key-value expression, we don't want a snippet.
	if clInfo.kv != nil {
		return
	}

	// A plain snippet turns "Foo{Ba<>" into "Foo{Bar: <>".
	snip.WriteText(": ")
	snip.WritePlaceholder(func(b *snippet.Builder) {
		// A placeholder snippet turns "Foo{Ba<>" into "Foo{Bar: <*int*>".
		if c.opts.placeholders {
			b.WriteText(detail)
		}
	})

	fset := c.pkg.FileSet()

	// If the cursor position is on a different line from the literal's opening brace,
	// we are in a multiline literal. Ignore line directives.
	if safetoken.StartPosition(fset, c.pos).Line != safetoken.StartPosition(fset, clInfo.cl.Lbrace).Line {
		snip.WriteText(",")
	}
}

// functionCallSnippet calculates the snippet for function calls.
func (c *completer) functionCallSnippet(name string, tparams, params []string, snip *snippet.Builder) {
	// If there is no suffix then we need to reuse existing call parens
	// "()" if present. If there is an identifier suffix then we always
	// need to include "()" since we don't overwrite the suffix.
	if c.surrounding != nil && c.surrounding.Suffix() == "" && len(c.path) > 1 {
		// If we are the left side (i.e. "Fun") part of a call expression,
		// we don't want a snippet since there are already parens present.
		switch n := c.path[1].(type) {
		case *ast.CallExpr:
			// The Lparen != Rparen check detects fudged CallExprs we
			// inserted when fixing the AST. In this case, we do still need
			// to insert the calling "()" parens.
			if n.Fun == c.path[0] && n.Lparen != n.Rparen {
				return
			}
		case *ast.SelectorExpr:
			if len(c.path) > 2 {
				if call, ok := c.path[2].(*ast.CallExpr); ok && call.Fun == c.path[1] && call.Lparen != call.Rparen {
					return
				}
			}
		}
	}

	snip.WriteText(name)

	if len(tparams) > 0 {
		snip.WriteText("[")
		if c.opts.placeholders {
			for i, tp := range tparams {
				if i > 0 {
					snip.WriteText(", ")
				}
				snip.WritePlaceholder(func(b *snippet.Builder) {
					b.WriteText(tp)
				})
			}
		} else {
			snip.WritePlaceholder(nil)
		}
		snip.WriteText("]")
	}

	snip.WriteText("(")

	if c.opts.placeholders {
		// A placeholder snippet turns "someFun<>" into "someFunc(<*i int*>, *s string*)".
		for i, p := range params {
			if i > 0 {
				snip.WriteText(", ")
			}
			snip.WritePlaceholder(func(b *snippet.Builder) {
				b.WriteText(p)
			})
		}
	} else {
		// A plain snippet turns "someFun<>" into "someFunc(<>)".
		if len(params) > 0 {
			snip.WritePlaceholder(nil)
		}
	}

	snip.WriteText(")")
}
