// 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 source

import (
	"context"
	"go/ast"
	"go/token"
	"math"
)

type labelType int

const (
	labelNone labelType = iota
	labelBreak
	labelContinue
	labelGoto
)

// wantLabelCompletion returns true if we want (only) label
// completions at the position.
func (c *completer) wantLabelCompletion() labelType {
	if _, ok := c.path[0].(*ast.Ident); ok && len(c.path) > 1 {
		// We want a label if we are an *ast.Ident child of a statement
		// that accepts a label, e.g. "break Lo<>".
		return takesLabel(c.path[1])
	}

	return labelNone
}

// takesLabel returns the corresponding labelType if n is a statement
// that accepts a label, otherwise labelNone.
func takesLabel(n ast.Node) labelType {
	if bs, ok := n.(*ast.BranchStmt); ok {
		switch bs.Tok {
		case token.BREAK:
			return labelBreak
		case token.CONTINUE:
			return labelContinue
		case token.GOTO:
			return labelGoto
		}
	}
	return labelNone
}

// labels adds completion items for labels defined in the enclosing
// function.
func (c *completer) labels(ctx context.Context, lt labelType) {
	if c.enclosingFunc == nil {
		return
	}

	addLabel := func(score float64, l *ast.LabeledStmt) {
		labelObj := c.pkg.GetTypesInfo().ObjectOf(l.Label)
		if labelObj != nil {
			c.found(ctx, candidate{obj: labelObj, score: score})
		}
	}

	switch lt {
	case labelBreak, labelContinue:
		// "break" and "continue" only accept labels from enclosing statements.

		for i, p := range c.path {
			switch p := p.(type) {
			case *ast.FuncLit:
				// Labels are function scoped, so don't continue out of functions.
				return
			case *ast.LabeledStmt:
				switch p.Stmt.(type) {
				case *ast.ForStmt, *ast.RangeStmt:
					// Loop labels can be used for "break" or "continue".
					addLabel(highScore*math.Pow(.99, float64(i)), p)
				case *ast.SwitchStmt, *ast.SelectStmt, *ast.TypeSwitchStmt:
					// Switch and select labels can be used only for "break".
					if lt == labelBreak {
						addLabel(highScore*math.Pow(.99, float64(i)), p)
					}
				}
			}
		}
	case labelGoto:
		// Goto accepts any label in the same function not in a nested
		// block. It also doesn't take labels that would jump across
		// variable definitions, but ignore that case for now.
		ast.Inspect(c.enclosingFunc.body, func(n ast.Node) bool {
			if n == nil {
				return false
			}

			switch n := n.(type) {
			// Only search into block-like nodes enclosing our "goto".
			// This prevents us from finding labels in nested blocks.
			case *ast.BlockStmt, *ast.CommClause, *ast.CaseClause:
				for _, p := range c.path {
					if n == p {
						return true
					}
				}
				return false
			case *ast.LabeledStmt:
				addLabel(highScore, n)
			}

			return true
		})
	}
}
