// Copyright 2018 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 lsp

import (
	"bytes"
	"context"
	"fmt"
	"strings"

	"golang.org/x/tools/internal/event"
	"golang.org/x/tools/internal/lsp/debug/tag"
	"golang.org/x/tools/internal/lsp/protocol"
	"golang.org/x/tools/internal/lsp/source"
	"golang.org/x/tools/internal/lsp/source/completion"
	"golang.org/x/tools/internal/lsp/template"
	"golang.org/x/tools/internal/span"
)

func (s *Server) completion(ctx context.Context, params *protocol.CompletionParams) (*protocol.CompletionList, error) {
	snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind)
	defer release()
	if !ok {
		return nil, err
	}
	var candidates []completion.CompletionItem
	var surrounding *completion.Selection
	switch snapshot.View().FileKind(fh) {
	case source.Go:
		candidates, surrounding, err = completion.Completion(ctx, snapshot, fh, params.Position, params.Context)
	case source.Mod:
		candidates, surrounding = nil, nil
	case source.Tmpl:
		var cl *protocol.CompletionList
		cl, err = template.Completion(ctx, snapshot, fh, params.Position, params.Context)
		if err != nil {
			break // use common error handling, candidates==nil
		}
		return cl, nil
	}
	if err != nil {
		event.Error(ctx, "no completions found", err, tag.Position.Of(params.Position))
	}
	if candidates == nil {
		return &protocol.CompletionList{
			IsIncomplete: true,
			Items:        []protocol.CompletionItem{},
		}, nil
	}
	// We might need to adjust the position to account for the prefix.
	rng, err := surrounding.Range()
	if err != nil {
		return nil, err
	}

	// internal/span treats end of file as the beginning of the next line, even
	// when it's not newline-terminated. We correct for that behaviour here if
	// end of file is not newline-terminated. See golang/go#41029.
	src, err := fh.Read()
	if err != nil {
		return nil, err
	}
	numLines := len(bytes.Split(src, []byte("\n")))
	tok := snapshot.FileSet().File(surrounding.Start())
	eof := tok.Pos(tok.Size())

	// For newline-terminated files, the line count reported by go/token should
	// be lower than the actual number of lines we see when splitting by \n. If
	// they're the same, the file isn't newline-terminated.
	if tok.Size() > 0 && tok.LineCount() == numLines {
		// Get the span for the last character in the file-1. This is
		// technically incorrect, but will get span to point to the previous
		// line.
		spn, err := span.NewRange(snapshot.FileSet(), eof-1, eof-1).Span()
		if err != nil {
			return nil, err
		}
		m := &protocol.ColumnMapper{
			URI:       fh.URI(),
			Converter: span.NewContentConverter(fh.URI().Filename(), src),
			Content:   src,
		}
		eofRng, err := m.Range(spn)
		if err != nil {
			return nil, err
		}
		// Instead of using the computed range, correct for our earlier
		// position adjustment by adding 1 to the column, not the line number.
		pos := protocol.Position{
			Line:      eofRng.Start.Line,
			Character: eofRng.Start.Character + 1,
		}
		if surrounding.Start() >= eof {
			rng.Start = pos
		}
		if surrounding.End() >= eof {
			rng.End = pos
		}
	}

	// When using deep completions/fuzzy matching, report results as incomplete so
	// client fetches updated completions after every key stroke.
	options := snapshot.View().Options()
	incompleteResults := options.DeepCompletion || options.Matcher == source.Fuzzy

	items := toProtocolCompletionItems(candidates, rng, options)

	return &protocol.CompletionList{
		IsIncomplete: incompleteResults,
		Items:        items,
	}, nil
}

func toProtocolCompletionItems(candidates []completion.CompletionItem, rng protocol.Range, options *source.Options) []protocol.CompletionItem {
	var (
		items                  = make([]protocol.CompletionItem, 0, len(candidates))
		numDeepCompletionsSeen int
	)
	for i, candidate := range candidates {
		// Limit the number of deep completions to not overwhelm the user in cases
		// with dozens of deep completion matches.
		if candidate.Depth > 0 {
			if !options.DeepCompletion {
				continue
			}
			if numDeepCompletionsSeen >= completion.MaxDeepCompletions {
				continue
			}
			numDeepCompletionsSeen++
		}
		insertText := candidate.InsertText
		if options.InsertTextFormat == protocol.SnippetTextFormat {
			insertText = candidate.Snippet()
		}

		// This can happen if the client has snippets disabled but the
		// candidate only supports snippet insertion.
		if insertText == "" {
			continue
		}

		item := protocol.CompletionItem{
			Label:  candidate.Label,
			Detail: candidate.Detail,
			Kind:   candidate.Kind,
			TextEdit: &protocol.TextEdit{
				NewText: insertText,
				Range:   rng,
			},
			InsertTextFormat:    options.InsertTextFormat,
			AdditionalTextEdits: candidate.AdditionalTextEdits,
			// This is a hack so that the client sorts completion results in the order
			// according to their score. This can be removed upon the resolution of
			// https://github.com/Microsoft/language-server-protocol/issues/348.
			SortText: fmt.Sprintf("%05d", i),

			// Trim operators (VSCode doesn't like weird characters in
			// filterText).
			FilterText: strings.TrimLeft(candidate.InsertText, "&*"),

			Preselect:     i == 0,
			Documentation: candidate.Documentation,
			Tags:          candidate.Tags,
			Deprecated:    candidate.Deprecated,
		}
		items = append(items, item)
	}
	return items
}
