// 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/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 fh.Kind() {
	case source.Go:
		candidates, surrounding, err = completion.Completion(ctx, snapshot, fh, params.Position, params.Context.TriggerCharacter)
	case source.Mod:
		candidates, surrounding = nil, nil
	}
	if err != nil {
		event.Error(ctx, "no completions found", err, tag.Position.Of(params.Position))
	}
	if candidates == nil {
		return &protocol.CompletionList{
			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,
		}
		items = append(items, item)
	}
	return items
}
