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

import (
	"bytes"
	"context"
	"encoding/json"
	"io"
	"net/http"
	"sort"
	"strings"

	"github.com/go-redis/redis/v7"
	"golang.org/x/pkgsite/internal/complete"
	"golang.org/x/pkgsite/internal/derrors"
	"golang.org/x/pkgsite/internal/log"
)

// handleAutoCompletion handles requests for /autocomplete?q=<input prefix>, by
// querying redis sorted sets indexing package paths.
func (s *Server) handleAutoCompletion(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	var completions []*complete.Completion
	if s.cmplClient != nil {
		var err error
		q := r.FormValue("q")
		completions, err = doCompletion(r.Context(), s.cmplClient, strings.ToLower(q), 5)
		if err != nil {
			code := http.StatusInternalServerError
			http.Error(w, http.StatusText(code), code)
			return
		}
	}
	if completions == nil {
		// autocomplete.js complains if the JSON returned by this endpoint is null,
		// so we initialize a non-nil empty array to serialize to an empty JSON
		// array.
		completions = []*complete.Completion{}
	}
	response, err := json.Marshal(completions)
	if err != nil {
		log.Errorf(ctx, "error marshalling completion: json.Marshal: %v", err)
	}
	w.Header().Set("Content-Type", "application/json")
	if _, err := io.Copy(w, bytes.NewReader(response)); err != nil {
		log.Errorf(ctx, "Error copying json buffer to ResponseWriter: %v", err)
	}
}

// scoredCompletion wraps Completions with a relevancy score, so that they can
// be sorted.
type scoredCompletion struct {
	c     *complete.Completion
	score int
}

// doCompletion executes the completion query against redis. This is inspired
// by http://oldblog.antirez.com/post/autocomplete-with-redis.html, but
// improved as follows:
//  + Use ZRANGEBYLEX to avoid storing each possible prefix, since that was
//    added to Redis since the original blog post.
//  + Use an additional sorted set that holds popular packages, to improve
//    completion relevancy.
//
// We autocomplete the query 'q' as follows
//  1. Query for popular completions starting with q using ZRANGEBYLEX (more
//     details on this below). We fetch an arbitrary number of results (1000)
//     to bound the amount of work done by redis.
//  2. Sort the returned completions by our score (a mix of popularity and
//     proximity to the end of the import path), and filter to the top
//     maxResults.
//  3. If we have maxResults results, we're done. Otherwise do (1) on the index
//     of remaining (unpopular) package paths, add to our result set, and sort
//     again (because unpopular packages might actually score higher than
//     popular packages).
func doCompletion(ctx context.Context, r *redis.Client, q string, maxResults int) (_ []*complete.Completion, err error) {
	defer derrors.Wrap(&err, "doCompletion(%q, %d)", q, maxResults)
	scored, err := completeWithIndex(ctx, r, q, complete.PopularKey, maxResults)
	if err != nil {
		return nil, err
	}
	if len(scored) < maxResults {
		unpopular, err := completeWithIndex(ctx, r, q, complete.RemainingKey, maxResults-len(scored))
		if err != nil {
			return nil, err
		}
		scored = append(scored, unpopular...)
		// Re-sort, as it is possible that an unpopular completion actually has a
		// higher score than a popular completion due to the weighting for suffix
		// length.
		sort.Slice(scored, func(i, j int) bool {
			return scored[i].score > scored[j].score
		})
	}
	var completions []*complete.Completion
	for _, s := range scored {
		completions = append(completions, s.c)
	}
	return completions, nil
}

func completeWithIndex(ctx context.Context, r *redis.Client, q, indexKey string, maxResults int) (_ []*scoredCompletion, err error) {
	defer derrors.Wrap(&err, "completeWithIndex(%q, %q, %d)", q, indexKey, maxResults)

	// Query for possible completions using ZRANGEBYLEX. See documentation at
	// https://redis.io/commands/zrangebylex
	// Notably, the "(" character in the Min and Max fields means 'exclude this
	// endpoint'.
	// We bound our search in two ways: (1) by setting Max to the smallest string
	// that lexically greater than q but does not start with q, and (2) by
	// setting an arbitrary limit of 1000 results.
	entries, err := r.WithContext(ctx).ZRangeByLex(indexKey, &redis.ZRangeBy{
		Min:   "(" + q,
		Max:   "(" + nextPrefix(q),
		Count: 1000,
	}).Result()
	var scored []*scoredCompletion
	for _, entry := range entries {
		c, err := complete.Decode(entry)
		if err != nil {
			return nil, err
		}
		offset := len(strings.Split(entry, "/"))
		s := &scoredCompletion{
			c: c,
			// Weight importers by distance of the matching text from the end of the
			// import path. This is done in an attempt to make results more relevant
			// the closer the match is to the end of the import path. For example, if
			// the user types 'net', we should have some preference for 'net' over
			// 'net/http'. In this case, it actually works out like so:
			//  - net has ~68000 importers
			//  - net/http has ~130000 importers
			//
			// So the score of 'net' is ~68000 (offset=1), and the score of
			// 'net/http' is ~65000 (130K/2, as offset=2), therefore net should be
			// sorted above 'net/http' in the results.
			//
			// This heuristic is a total guess, but since this is just autocomplete
			// it probably doesn't matter much. In testing, it felt like autocomplete
			// was completing the packages I wanted.
			//
			// The `- offset` term is added to break ties in the case where all
			// completion results have 0 importers.
			score: c.Importers/offset - offset,
		}
		scored = append(scored, s)
	}
	// sort by score descending
	sort.Slice(scored, func(i, j int) bool {
		return scored[i].score > scored[j].score
	})
	if len(scored) > maxResults {
		scored = scored[:maxResults]
	}
	return scored, nil
}

// nextPrefix returns the first string (according to lexical sorting) that is
// greater than prefix but does not start with prefix.
func nextPrefix(prefix string) string {
	// redis strings are ASCII. Note that among printing ASCII characters '!' has
	// the smallest byte value and '~' has the largest byte value. It also so
	// happens that these are both valid characters in a URL.
	if prefix == "" {
		return ""
	}
	lastChar := prefix[len(prefix)-1]
	if lastChar >= '~' {
		// If the last character is '~', there is no greater ascii character so we
		// must move to the previous character to find a lexically greater string
		// that doesn't start with prefix. Note that in the degenerate case where
		// prefix is nothing but twiddles (e.g. "~~~"), we will recurse until we return "",
		// which is acceptable: there is no prefix that satisfies our requirements:
		// all strings greater than "~~~" must also start with "~~~"
		return nextPrefix(prefix[:len(prefix)-1])
	}
	return prefix[:len(prefix)-1] + string(lastChar+1)
}
