package mod

import (
	"bytes"
	"context"
	"fmt"
	"go/token"
	"strings"

	"golang.org/x/mod/modfile"
	"golang.org/x/tools/internal/event"
	"golang.org/x/tools/internal/lsp/protocol"
	"golang.org/x/tools/internal/lsp/source"
	"golang.org/x/tools/internal/span"
	errors "golang.org/x/xerrors"
)

func Hover(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, position protocol.Position) (*protocol.Hover, error) {
	uri := snapshot.View().ModFile()

	// For now, we only provide hover information for the view's go.mod file.
	if uri == "" || fh.URI() != uri {
		return nil, nil
	}

	ctx, done := event.Start(ctx, "mod.Hover")
	defer done()

	// Get the position of the cursor.
	pm, err := snapshot.ParseMod(ctx, fh)
	if err != nil {
		return nil, errors.Errorf("getting modfile handle: %w", err)
	}
	spn, err := pm.Mapper.PointSpan(position)
	if err != nil {
		return nil, errors.Errorf("computing cursor position: %w", err)
	}
	hoverRng, err := spn.Range(pm.Mapper.Converter)
	if err != nil {
		return nil, errors.Errorf("computing hover range: %w", err)
	}

	// Confirm that the cursor is at the position of a require statement.
	var req *modfile.Require
	var startPos, endPos int
	for _, r := range pm.File.Require {
		dep := []byte(r.Mod.Path)
		s, e := r.Syntax.Start.Byte, r.Syntax.End.Byte
		i := bytes.Index(pm.Mapper.Content[s:e], dep)
		if i == -1 {
			continue
		}
		// Shift the start position to the location of the
		// dependency within the require statement.
		startPos, endPos = s+i, s+i+len(dep)
		if token.Pos(startPos) <= hoverRng.Start && hoverRng.Start <= token.Pos(endPos) {
			req = r
			break
		}
	}

	// The cursor position is not on a require statement.
	if req == nil {
		return nil, nil
	}

	// Get the `go mod why` results for the given file.
	why, err := snapshot.ModWhy(ctx, fh)
	if err != nil {
		return nil, err
	}
	explanation, ok := why[req.Mod.Path]
	if !ok {
		return nil, nil
	}

	// Get the range to highlight for the hover.
	line, col, err := pm.Mapper.Converter.ToPosition(startPos)
	if err != nil {
		return nil, err
	}
	start := span.NewPoint(line, col, startPos)

	line, col, err = pm.Mapper.Converter.ToPosition(endPos)
	if err != nil {
		return nil, err
	}
	end := span.NewPoint(line, col, endPos)

	spn = span.New(fh.URI(), start, end)
	rng, err := pm.Mapper.Range(spn)
	if err != nil {
		return nil, err
	}
	options := snapshot.View().Options()
	isPrivate := snapshot.View().IsGoPrivatePath(req.Mod.Path)
	explanation = formatExplanation(explanation, req, options, isPrivate)
	return &protocol.Hover{
		Contents: protocol.MarkupContent{
			Kind:  options.PreferredContentFormat,
			Value: explanation,
		},
		Range: rng,
	}, nil
}

func formatExplanation(text string, req *modfile.Require, options source.Options, isPrivate bool) string {
	text = strings.TrimSuffix(text, "\n")
	splt := strings.Split(text, "\n")
	length := len(splt)

	var b strings.Builder
	// Write the heading as an H3.
	b.WriteString("##" + splt[0])
	if options.PreferredContentFormat == protocol.Markdown {
		b.WriteString("\n\n")
	} else {
		b.WriteRune('\n')
	}

	// If the explanation is 2 lines, then it is of the form:
	// # golang.org/x/text/encoding
	// (main module does not need package golang.org/x/text/encoding)
	if length == 2 {
		b.WriteString(splt[1])
		return b.String()
	}

	imp := splt[length-1] // import path
	reference := imp
	// See golang/go#36998: don't link to modules matching GOPRIVATE.
	if !isPrivate && options.PreferredContentFormat == protocol.Markdown {
		target := imp
		if strings.ToLower(options.LinkTarget) == "pkg.go.dev" {
			target = strings.Replace(target, req.Mod.Path, req.Mod.String(), 1)
		}
		reference = fmt.Sprintf("[%s](https://%s/%s)", imp, options.LinkTarget, target)
	}
	b.WriteString("This module is necessary because " + reference + " is imported in")

	// If the explanation is 3 lines, then it is of the form:
	// # golang.org/x/tools
	// modtest
	// golang.org/x/tools/go/packages
	if length == 3 {
		msg := fmt.Sprintf(" `%s`.", splt[1])
		b.WriteString(msg)
		return b.String()
	}

	// If the explanation is more than 3 lines, then it is of the form:
	// # golang.org/x/text/language
	// rsc.io/quote
	// rsc.io/sampler
	// golang.org/x/text/language
	b.WriteString(":\n```text")
	dash := ""
	for _, imp := range splt[1 : length-1] {
		dash += "-"
		b.WriteString("\n" + dash + " " + imp)
	}
	b.WriteString("\n```")
	return b.String()
}
