// 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"
	"html/template"
	"log"
	"net/url"
	"strconv"
	"strings"

	"github.com/google/zoekt"
)

func (s *Server) formatResults(result *zoekt.SearchResult, query string, localPrint bool) ([]*FileMatch, error) {
	var fmatches []*FileMatch

	templateMap := map[string]*template.Template{}
	fragmentMap := map[string]*template.Template{}
	if !localPrint {
		for repo, str := range result.RepoURLs {
			if str != "" {
				templateMap[repo] = s.getTemplate(str)
			}
		}
		for repo, str := range result.LineFragments {
			if str != "" {
				fragmentMap[repo] = s.getTemplate(str)
			}
		}
	}
	getFragment := func(repo string, linenum int) string {
		tpl := fragmentMap[repo]

		if tpl == nil || localPrint {
			return "#l" + strconv.Itoa(linenum)
		}

		var buf bytes.Buffer
		if err := tpl.Execute(&buf, map[string]string{
			"LineNumber": strconv.Itoa(linenum),
		}); err != nil {
			log.Printf("fragment template: %v", err)
			return ""
		}
		return buf.String()
	}
	getURL := func(repo, filename string, branches []string, version string) string {
		tpl := templateMap[repo]
		if localPrint || tpl == nil {
			v := make(url.Values)
			v.Add("r", repo)
			v.Add("f", filename)
			v.Add("q", query)
			if len(branches) > 0 {
				v.Add("b", branches[0])
			}
			return "print?" + v.Encode()
		}

		var buf bytes.Buffer
		b := ""
		if len(branches) > 0 {
			b = branches[0]
		}
		err := tpl.Execute(&buf, map[string]string{
			"Branch":  b,
			"Version": version,
			"Path":    filename,
		})
		if err != nil {
			log.Printf("url template: %v", err)
			return ""
		}
		return buf.String()
	}

	// hash => result-id
	seenFiles := map[string]string{}
	for _, f := range result.Files {
		fMatch := FileMatch{
			FileName: f.FileName,
			Repo:     f.Repository,
			ResultID: f.Repository + ":" + f.FileName,
			Branches: f.Branches,
			Language: f.Language,
		}

		if dup, ok := seenFiles[string(f.Checksum)]; ok {
			fMatch.DuplicateID = dup
		} else {
			seenFiles[string(f.Checksum)] = fMatch.ResultID
		}

		if f.SubRepositoryName != "" {
			fn := strings.TrimPrefix(fMatch.FileName[len(f.SubRepositoryPath):], "/")
			fMatch.URL = getURL(f.SubRepositoryName, fn, f.Branches, f.Version)
		} else {
			fMatch.URL = getURL(f.Repository, f.FileName, f.Branches, f.Version)
		}

		for _, m := range f.LineMatches {
			fragment := getFragment(f.Repository, m.LineNumber)
			if !strings.HasPrefix(fragment, "#") && !strings.HasPrefix(fragment, ";") {
				// TODO - remove this is backward compatibility glue.
				fragment = "#" + fragment
			}
			md := Match{
				FileName: f.FileName,
				LineNum:  m.LineNumber,
				URL:      fMatch.URL + fragment,
			}

			lastEnd := 0
			line := m.Line
			for i, f := range m.LineFragments {
				l := f.LineOffset
				e := l + f.MatchLength

				frag := Fragment{
					Pre:   string(line[lastEnd:l]),
					Match: string(line[l:e]),
				}
				if i == len(m.LineFragments)-1 {
					frag.Post = string(m.Line[e:])
				}

				md.Fragments = append(md.Fragments, frag)
				lastEnd = e
			}
			fMatch.Matches = append(fMatch.Matches, md)
		}
		fmatches = append(fmatches, &fMatch)
	}
	return fmatches, nil
}
