// Copyright 2016 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package web

import (
	"bytes"
	"fmt"
	"html/template"
	"log"
	"net"
	"net/http"
	"regexp"
	"regexp/syntax"
	"sort"
	"strconv"
	"strings"
	"sync"
	"time"

	"golang.org/x/net/context"

	"github.com/google/zoekt"
	"github.com/google/zoekt/query"
)

var Funcmap = template.FuncMap{
	"Inc": func(orig int) int {
		return orig + 1
	},
	"More": func(orig int) int {
		return orig * 3
	},
	"HumanUnit": func(orig int64) string {
		b := orig
		suffix := ""
		if orig > 10*(1<<30) {
			suffix = "G"
			b = orig / (1 << 30)
		} else if orig > 10*(1<<20) {
			suffix = "M"
			b = orig / (1 << 20)
		} else if orig > 10*(1<<10) {
			suffix = "K"
			b = orig / (1 << 10)
		}

		return fmt.Sprintf("%d%s", b, suffix)
	},
	"LimitPre": func(limit int, pre string) string {
		if len(pre) < limit {
			return pre
		}
		return fmt.Sprintf("...(%d bytes skipped)...%s", len(pre)-limit, pre[len(pre)-limit:])
	},
	"LimitPost": func(limit int, post string) string {
		if len(post) < limit {
			return post
		}
		return fmt.Sprintf("%s...(%d bytes skipped)...", post[:limit], len(post)-limit)
	},
}

const defaultNumResults = 50

type Server struct {
	Searcher zoekt.Searcher

	// Serve HTML interface
	HTML bool

	// If set, show files from the index.
	Print bool

	// Version string for this server.
	Version string

	// Depending on the Host header, add a query to the entry
	// page. For example, when serving on "search.myproject.org"
	// we could add "r:myproject" automatically.  This allows a
	// single instance to serve as search engine for multiple
	// domains.
	HostCustomQueries map[string]string

	// This should contain the following templates: "didyoumean"
	// (for suggestions), "repolist" (for the repo search result
	// page), "result" for the search results, "search" (for the
	// opening page), "box" for the search query input element and
	// "print" for the show file functionality.
	Top *template.Template

	didYouMean *template.Template
	repolist   *template.Template
	search     *template.Template
	result     *template.Template
	print      *template.Template
	about      *template.Template

	startTime time.Time

	templateMu    sync.Mutex
	templateCache map[string]*template.Template

	lastStatsMu sync.Mutex
	lastStats   *zoekt.RepoStats
	lastStatsTS time.Time
}

func (s *Server) getTemplate(str string) *template.Template {
	s.templateMu.Lock()
	defer s.templateMu.Unlock()
	t := s.templateCache[str]
	if t != nil {
		return t
	}

	t, err := template.New("cache").Parse(str)
	if err != nil {
		log.Printf("template parse error: %v", err)
		t = template.Must(template.New("empty").Parse(""))
	}
	s.templateCache[str] = t
	return t
}

func NewMux(s *Server) (*http.ServeMux, error) {
	s.print = s.Top.Lookup("print")
	if s.print == nil {
		return nil, fmt.Errorf("missing template 'print'")
	}

	for k, v := range map[string]**template.Template{
		"didyoumean": &s.didYouMean,
		"results":    &s.result,
		"print":      &s.print,
		"search":     &s.search,
		"repolist":   &s.repolist,
		"about":      &s.about,
	} {
		*v = s.Top.Lookup(k)
		if *v == nil {
			return nil, fmt.Errorf("missing template %q", k)
		}
	}

	s.templateCache = map[string]*template.Template{}
	s.startTime = time.Now()

	mux := http.NewServeMux()

	if s.HTML {
		mux.HandleFunc("/search", s.serveSearch)
		mux.HandleFunc("/", s.serveSearchBox)
		mux.HandleFunc("/about", s.serveAbout)
		mux.HandleFunc("/print", s.servePrint)
	}

	return mux, nil
}

func (s *Server) serveSearch(w http.ResponseWriter, r *http.Request) {
	err := s.serveSearchErr(w, r)

	if suggest, ok := err.(*query.SuggestQueryError); ok {
		var buf bytes.Buffer
		if err := s.didYouMean.Execute(&buf, suggest); err != nil {
			http.Error(w, err.Error(), http.StatusTeapot)
		}

		w.Write(buf.Bytes())
		return
	}

	if err != nil {
		http.Error(w, err.Error(), http.StatusTeapot)
	}
}

func (s *Server) serveSearchErr(w http.ResponseWriter, r *http.Request) error {
	qvals := r.URL.Query()
	queryStr := qvals.Get("q")
	if queryStr == "" {
		return fmt.Errorf("no query found")
	}

	q, err := query.Parse(queryStr)
	if err != nil {
		return err
	}

	repoOnly := true
	query.VisitAtoms(q, func(q query.Q) {
		_, ok := q.(*query.Repo)
		repoOnly = repoOnly && ok
	})
	if repoOnly {
		return s.serveListReposErr(q, queryStr, w, r)
	}

	numStr := qvals.Get("num")

	num, err := strconv.Atoi(numStr)
	if err != nil || num <= 0 {
		num = defaultNumResults
	}

	sOpts := zoekt.SearchOptions{
		MaxWallTime: 10 * time.Second,
	}

	sOpts.SetDefaults()

	ctx := r.Context()
	if result, err := s.Searcher.Search(ctx, q, &zoekt.SearchOptions{EstimateDocCount: true}); err != nil {
		return err
	} else if numdocs := result.ShardFilesConsidered; numdocs > 10000 {
		// If the search touches many shards and many files, we
		// have to limit the number of matches.  This setting
		// is based on the number of documents eligible after
		// considering reponames, so large repos (both
		// android, chromium are about 500k files) aren't
		// covered fairly.

		// 10k docs, 50 num -> max match = (250 + 250 / 10)
		sOpts.ShardMaxMatchCount = num*5 + (5*num)/(numdocs/1000)

		// 10k docs, 50 num -> max important match = 4
		sOpts.ShardMaxImportantMatch = num/20 + num/(numdocs/500)
	} else {
		// Virtually no limits for a small corpus; important
		// matches are just as expensive as normal matches.
		n := numdocs + num*100
		sOpts.ShardMaxImportantMatch = n
		sOpts.ShardMaxMatchCount = n
		sOpts.TotalMaxMatchCount = n
		sOpts.TotalMaxImportantMatch = n
	}
	sOpts.MaxDocDisplayCount = num

	result, err := s.Searcher.Search(ctx, q, &sOpts)
	if err != nil {
		return err
	}

	fileMatches, err := s.formatResults(result, queryStr, s.Print)
	if err != nil {
		return err
	}

	res := ResultInput{
		Last: LastInput{
			Query:     queryStr,
			Num:       num,
			AutoFocus: true,
		},
		Stats:         result.Stats,
		Query:         q.String(),
		QueryStr:      queryStr,
		SearchOptions: sOpts.String(),
		FileMatches:   fileMatches,
	}
	if res.Stats.Wait < res.Stats.Duration/10 {
		// Suppress queueing stats if they are neglible.
		res.Stats.Wait = 0
	}

	var buf bytes.Buffer
	if err := s.result.Execute(&buf, &res); err != nil {
		return err
	}

	w.Write(buf.Bytes())
	return nil
}

func (s *Server) servePrint(w http.ResponseWriter, r *http.Request) {
	err := s.servePrintErr(w, r)
	if err != nil {
		http.Error(w, err.Error(), http.StatusTeapot)
	}
}

const statsStaleNess = 30 * time.Second

func (s *Server) fetchStats(ctx context.Context) (*zoekt.RepoStats, error) {
	s.lastStatsMu.Lock()
	stats := s.lastStats
	if time.Since(s.lastStatsTS) > statsStaleNess {
		stats = nil
	}
	s.lastStatsMu.Unlock()

	if stats != nil {
		return stats, nil
	}

	repos, err := s.Searcher.List(ctx, &query.Const{Value: true})
	if err != nil {
		return nil, err
	}

	stats = &zoekt.RepoStats{}
	names := map[string]struct{}{}
	for _, r := range repos.Repos {
		stats.Add(&r.Stats)
		names[r.Repository.Name] = struct{}{}
	}
	stats.Repos = len(names)

	s.lastStatsMu.Lock()
	s.lastStatsTS = time.Now()
	s.lastStats = stats
	s.lastStatsMu.Unlock()

	return stats, nil
}

func (s *Server) serveSearchBoxErr(w http.ResponseWriter, r *http.Request) error {
	stats, err := s.fetchStats(r.Context())
	if err != nil {
		return err
	}
	d := SearchBoxInput{
		Last: LastInput{
			Num:       defaultNumResults,
			AutoFocus: true,
		},
		Stats:   stats,
		Version: s.Version,
		Uptime:  time.Since(s.startTime),
	}

	d.Last.Query = r.URL.Query().Get("q")
	if d.Last.Query == "" {
		custom := s.HostCustomQueries[r.Host]
		if custom == "" {
			host, _, _ := net.SplitHostPort(r.Host)
			custom = s.HostCustomQueries[host]
		}

		if custom != "" {
			d.Last.Query = custom + " "
		}
	}

	var buf bytes.Buffer
	if err := s.search.Execute(&buf, &d); err != nil {
		return err
	}
	w.Write(buf.Bytes())
	return nil
}

func (s *Server) serveSearchBox(w http.ResponseWriter, r *http.Request) {
	if err := s.serveSearchBoxErr(w, r); err != nil {
		http.Error(w, err.Error(), http.StatusTeapot)
	}
}

func (s *Server) serveAboutErr(w http.ResponseWriter, r *http.Request) error {
	stats, err := s.fetchStats(r.Context())
	if err != nil {
		return err
	}

	d := SearchBoxInput{
		Stats:   stats,
		Version: s.Version,
		Uptime:  time.Since(s.startTime),
	}

	var buf bytes.Buffer
	if err := s.about.Execute(&buf, &d); err != nil {
		return err
	}
	w.Write(buf.Bytes())
	return nil
}

func (s *Server) serveAbout(w http.ResponseWriter, r *http.Request) {
	if err := s.serveAboutErr(w, r); err != nil {
		http.Error(w, err.Error(), http.StatusTeapot)
	}
}

func (s *Server) serveListReposErr(q query.Q, qStr string, w http.ResponseWriter, r *http.Request) error {
	ctx := r.Context()
	repos, err := s.Searcher.List(ctx, q)
	if err != nil {
		return err
	}

	qvals := r.URL.Query()
	order := qvals.Get("order")
	switch order {
	case "", "name", "revname":
		sort.Slice(repos.Repos, func(i, j int) bool {
			return strings.Compare(repos.Repos[i].Repository.Name, repos.Repos[j].Repository.Name) < 0
		})
	case "size", "revsize":
		sort.Slice(repos.Repos, func(i, j int) bool {
			return repos.Repos[i].Stats.ContentBytes < repos.Repos[j].Stats.ContentBytes
		})
	case "time", "revtime":
		sort.Slice(repos.Repos, func(i, j int) bool {
			return repos.Repos[i].IndexMetadata.IndexTime.Before(
				repos.Repos[j].IndexMetadata.IndexTime)
		})
	default:
		return fmt.Errorf("got unknown sort key %q, allowed [rev]name, [rev]time, [rev]size", order)
	}
	if strings.HasPrefix(order, "rev") {
		for i, j := 0, len(repos.Repos)-1; i < j; {
			repos.Repos[i], repos.Repos[j] = repos.Repos[j], repos.Repos[i]
			i++
			j--

		}
	}

	aggregate := zoekt.RepoStats{
		Repos: len(repos.Repos),
	}
	for _, s := range repos.Repos {
		aggregate.Add(&s.Stats)
	}
	res := RepoListInput{
		Last: LastInput{
			Query:     qStr,
			AutoFocus: true,
		},
		Stats: aggregate,
	}

	numStr := qvals.Get("num")
	num, err := strconv.Atoi(numStr)
	if err != nil || num <= 0 {
		num = 0
	}
	if num > 0 {
		if num > len(repos.Repos) {
			num = len(repos.Repos)
		}

		repos.Repos = repos.Repos[:num]
	}

	for _, r := range repos.Repos {
		t := s.getTemplate(r.Repository.CommitURLTemplate)

		repo := Repository{
			Name:      r.Repository.Name,
			URL:       r.Repository.URL,
			IndexTime: r.IndexMetadata.IndexTime,
			Size:      r.Stats.ContentBytes,
			Files:     int64(r.Stats.Documents),
		}
		for _, b := range r.Repository.Branches {
			var buf bytes.Buffer
			if err := t.Execute(&buf, b); err != nil {
				return err
			}
			repo.Branches = append(repo.Branches,
				Branch{
					Name:    b.Name,
					Version: b.Version,
					URL:     buf.String(),
				})
		}
		res.Repos = append(res.Repos, repo)
	}

	var buf bytes.Buffer
	if err := s.repolist.Execute(&buf, &res); err != nil {
		return err
	}

	w.Write(buf.Bytes())
	return nil
}

func (s *Server) servePrintErr(w http.ResponseWriter, r *http.Request) error {
	qvals := r.URL.Query()
	fileStr := qvals.Get("f")
	repoStr := qvals.Get("r")
	queryStr := qvals.Get("q")
	numStr := qvals.Get("num")
	num, err := strconv.Atoi(numStr)
	if err != nil || num <= 0 {
		num = defaultNumResults
	}

	re, err := syntax.Parse("^"+regexp.QuoteMeta(fileStr)+"$", 0)
	if err != nil {
		return err
	}
	qs := []query.Q{
		&query.Regexp{Regexp: re, FileName: true, CaseSensitive: true},
		&query.Repo{Pattern: repoStr},
	}

	if branchStr := qvals.Get("b"); branchStr != "" {
		qs = append(qs, &query.Branch{Pattern: branchStr})
	}

	q := &query.And{Children: qs}

	sOpts := zoekt.SearchOptions{
		Whole: true,
	}

	ctx := r.Context()
	result, err := s.Searcher.Search(ctx, q, &sOpts)
	if err != nil {
		return err
	}

	if len(result.Files) != 1 {
		var ss []string
		for _, n := range result.Files {
			ss = append(ss, n.FileName)
		}
		return fmt.Errorf("ambiguous result: %v", ss)
	}

	f := result.Files[0]

	byteLines := bytes.Split(f.Content, []byte{'\n'})
	strLines := make([]string, 0, len(byteLines))
	for _, l := range byteLines {
		strLines = append(strLines, string(l))
	}

	d := PrintInput{
		Name:  f.FileName,
		Repo:  f.Repository,
		Lines: strLines,
		Last: LastInput{
			Query:     queryStr,
			Num:       num,
			AutoFocus: false,
		},
	}

	var buf bytes.Buffer
	if err := s.print.Execute(&buf, &d); err != nil {
		return err
	}

	w.Write(buf.Bytes())
	return nil
}
