package source

import (
	"go/ast"

	"golang.org/x/tools/internal/lsp/protocol"
)

const (
	BREAK       = "break"
	CASE        = "case"
	CHAN        = "chan"
	CONST       = "const"
	CONTINUE    = "continue"
	DEFAULT     = "default"
	DEFER       = "defer"
	ELSE        = "else"
	FALLTHROUGH = "fallthrough"
	FOR         = "for"
	FUNC        = "func"
	GO          = "go"
	GOTO        = "goto"
	IF          = "if"
	IMPORT      = "import"
	INTERFACE   = "interface"
	MAP         = "map"
	PACKAGE     = "package"
	RANGE       = "range"
	RETURN      = "return"
	SELECT      = "select"
	STRUCT      = "struct"
	SWITCH      = "switch"
	TYPE        = "type"
	VAR         = "var"
)

// addKeywordCompletions offers keyword candidates appropriate at the position.
func (c *completer) addKeywordCompletions() {
	seen := make(map[string]bool)

	if c.wantTypeName() {
		// If we expect a type name, include "interface", "struct",
		// "func", "chan", and "map".

		// "interface" and "struct" are more common declaring named types.
		// Give them a higher score if we are in a type declaration.
		structIntf, funcChanMap := stdScore, highScore
		if len(c.path) > 1 {
			if _, namedDecl := c.path[1].(*ast.TypeSpec); namedDecl {
				structIntf, funcChanMap = highScore, stdScore
			}
		}

		c.addKeywordItems(seen, structIntf, STRUCT, INTERFACE)
		c.addKeywordItems(seen, funcChanMap, FUNC, CHAN, MAP)
	}

	// If we are at the file scope, only offer decl keywords. We don't
	// get *ast.Idents at the file scope because non-keyword identifiers
	// turn into *ast.BadDecl, not *ast.Ident.
	if len(c.path) == 1 || isASTFile(c.path[1]) {
		c.addKeywordItems(seen, stdScore, TYPE, CONST, VAR, FUNC, IMPORT)
		return
	} else if _, ok := c.path[0].(*ast.Ident); !ok {
		// Otherwise only offer keywords if the client is completing an identifier.
		return
	}

	if len(c.path) > 2 {
		// Offer "range" if we are in ast.ForStmt.Init. This is what the
		// AST looks like before "range" is typed, e.g. "for i := r<>".
		if loop, ok := c.path[2].(*ast.ForStmt); ok && nodeContains(loop.Init, c.pos) {
			c.addKeywordItems(seen, stdScore, RANGE)
		}
	}

	// Only suggest keywords if we are beginning a statement.
	switch n := c.path[1].(type) {
	case *ast.BlockStmt, *ast.ExprStmt:
		// OK - our ident must be at beginning of statement.
	case *ast.CommClause:
		// Make sure we aren't in the Comm statement.
		if !n.Colon.IsValid() || c.pos <= n.Colon {
			return
		}
	case *ast.CaseClause:
		// Make sure we aren't in the case List.
		if !n.Colon.IsValid() || c.pos <= n.Colon {
			return
		}
	default:
		return
	}

	// Filter out keywords depending on scope
	// Skip the first one because we want to look at the enclosing scopes
	path := c.path[1:]
	for i, n := range path {
		switch node := n.(type) {
		case *ast.CaseClause:
			// only recommend "fallthrough" and "break" within the bodies of a case clause
			if c.pos > node.Colon {
				c.addKeywordItems(seen, stdScore, BREAK)
				// "fallthrough" is only valid in switch statements.
				// A case clause is always nested within a block statement in a switch statement,
				// that block statement is nested within either a TypeSwitchStmt or a SwitchStmt.
				if i+2 >= len(path) {
					continue
				}
				if _, ok := path[i+2].(*ast.SwitchStmt); ok {
					c.addKeywordItems(seen, stdScore, FALLTHROUGH)
				}
			}
		case *ast.CommClause:
			if c.pos > node.Colon {
				c.addKeywordItems(seen, stdScore, BREAK)
			}
		case *ast.TypeSwitchStmt, *ast.SelectStmt, *ast.SwitchStmt:
			c.addKeywordItems(seen, stdScore, CASE, DEFAULT)
		case *ast.ForStmt, *ast.RangeStmt:
			c.addKeywordItems(seen, stdScore, BREAK, CONTINUE)
		// This is a bit weak, functions allow for many keywords
		case *ast.FuncDecl:
			if node.Body != nil && c.pos > node.Body.Lbrace {
				c.addKeywordItems(seen, stdScore, DEFER, RETURN, FOR, GO, SWITCH, SELECT, IF, ELSE, VAR, CONST, GOTO, TYPE)
			}
		}
	}
}

// addKeywordItems dedupes and adds completion items for the specified
// keywords with the specified score.
func (c *completer) addKeywordItems(seen map[string]bool, score float64, kws ...string) {
	for _, kw := range kws {
		if seen[kw] {
			continue
		}
		seen[kw] = true

		if matchScore := c.matcher.Score(kw); matchScore > 0 {
			c.items = append(c.items, CompletionItem{
				Label:      kw,
				Kind:       protocol.KeywordCompletion,
				InsertText: kw,
				Score:      score * float64(matchScore),
			})
		}
	}
}
