// 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 (
	"html/template"
	"log"
)

// Top provides the standard templates in parsed form
var Top = template.New("top").Funcs(Funcmap)

// TemplateText contains the text of the standard templates.
var TemplateText = map[string]string{

	"didyoumean": `<html>
  <head>
    <title>Error</title>
  </head>
  <body>
    <p>{{.Message}}. Did you mean <a href="/search?q={{.Suggestion}}">{{.Suggestion}}</a> ?
  </body>
</html>
`,

	// the template for the search box.
	"searchbox": `
  <form action="search">
    Search some code: <input
      autofocus
      onfocus="this.value = this.value;"
      {{if .Query}}value={{.Query}}
      {{end}}type="text" name="q"> Max results:  <input style="width: 5em;" type="text" name="num" value="{{.Num}}"> <input type="submit" value="Search">
  </form>
`,

	// search box for the entry page.
	"search": `<html>
<head>
<style>
dt {
    font-family: monospace;
}
</style>
</head>
<title>Zoekt, en gij zult spinazie eten</title>
<body>
<div style="margin: 3em; padding 3em; position: center;">
{{template "searchbox" .Last}}
</div>

<div style="display: flex; justify-content: space-around; flex-direction: row;">

<div>
  Search examples:
  <div style="margin-left: 4em;">
  <dl>
    <dt><a href="search?q=needle">needle</a></dt><dd>search for "needle"
  </dd>
    <dt><a href="search?q=thread+or+needle">thread or needle</a></dt><dd>search for either "thread" or "needle"
  </dd>
    <dt><a href="search?q=class+needle">class needle</a></dt><dd>search for files containing both "class" and "needle"
  </dd>
    <dt><a href="search?q=class+Needle">class Needle</a></dt><dd>search for files containing both "class" (case insensitive) and "Needle" (case sensitive)
  </dd>
    <dt><a href="search?q=class+Needle+case:yes">class Needle case:yes</a></dt><dd>search for files containing "class" and "Needle", both case sensitively
  </dd>
    <dt><a href="search?q=%22class Needle%22">"class Needle"</a></dt><dd>search for files with the phrase "class Needle"
  </dd>
     <dt><a href="search?q=needle+-hay">needle -hay</a></dt><dd>search for files with the word "needle" but not the word "hay"
  </dd>
    <dt><a href="search?q=path+file:java">path file:java</a></dt><dd>search for the word "path" in files whose name contains "java"
  </dd>
    <dt><a href="search?q=f:%5C.c%24">f:\.c$</a></dt><dd>search for files whose name ends with ".c"
  </dd>
    <dt><a href="search?q=path+-file:java">path -file:java</a></dt><dd>search for the word "path" excluding files whose name contains "java"</dd>
    <dt><a href="search?q=foo.*bar">foo.*bar</a></dt><dd>search for the regular expression "foo.*bar"</dd>
    <dt><a href="search?q=-%28Path File%29 Stream">-(Path File) Stream</a></dt><dd>search "Stream", but exclude files containing both "Path" and "File"</dd>
    <dt><a href="search?q=-Path%5c+file+Stream">-Path\ file Stream</a></dt><dd>search "Stream", but exclude files containing "Path File"</dd>
    <dt><a href="search?q=phone+r:doid">phone r:droid</a></dt><dd>search for "phone" in repositories whose name contains "droid"</dd>
    <dt><a href="search?q=phone+b:aster">phone b:aster</a></dt><dd>for Git repos, find "phone" in files in branches whose name contains "aster".</dd>
    <dt><a href="search?q=phone+b:HEAD">phone b:HEAD</a></dt><dd>for Git repos, find "phone" in the default ('HEAD') branch.</dd>
  </dl>
  </div>
</div>

<div>

<p>
Used {{HumanUnit .Stats.IndexBytes}} memory for
{{.Stats.Documents}} documents ({{HumanUnit .Stats.ContentBytes}})
from {{.Stats.Repos}} repositories.


<p>
To list repositories, try:
  <div style="margin-left: 4em;">
  <dl>
    <dt><a href="search?q=r:droid">r:droid</a></dt><dd>list repositories whose name contains "droid".</dd>
    <dt><a href="search?q=r:go+-r:google">r:go -r:google</a></dt><dd>list repositories whose name contains "go" but not "google".</dd>
  </dl>
  </div>
</p>
</div>
</div>

<hr>

<div>
<a href="about">About</a>
</div>

</body>
</html>
`,

	"results": `<html>
  <head>
    <title>Results for {{.QueryStr}}</title>
  </head>
<body>
  {{template "searchbox" .Last}}
<hr>
  {{if .Stats.Crashes}}<br><b>{{.Stats.Crashes}} shards crashed</b><br>{{end}}
  Found {{.Stats.MatchCount}} results in {{.Stats.FileCount}} files ({{.Stats.NgramMatches}} ngram matches,
    {{.Stats.FilesConsidered}} docs considered, {{.Stats.FilesLoaded}} docs ({{HumanUnit .Stats.BytesLoaded}}B) loaded,
    {{.Stats.FilesSkipped}} docs skipped): for
  <pre style="background: #ffc;">{{.Query}} with options {{.SearchOptions}}</pre>
  in {{.Stats.Duration}} (queued: {{.Stats.Wait}})
  <p>
  {{range .FileMatches}}
    {{if .URL}}<a href="{{.URL}}">{{end}}
    <tt><b>{{.Repo}}</b>:<b>{{.FileName}}</b>{{if .URL}}</a>{{end}}:{{if .Branches}}<small>[{{range .Branches}}{{.}}, {{end}}]</small>{{end}} </tt>

      <div style="background: #eef;">
    {{range .Matches}}
        <pre>{{if .URL}}<a href="{{.URL}}">{{end}}{{.LineNum}}{{if .URL}}</a>{{end}}: {{range .Fragments}}{{.Pre}}<b>{{.Match}}</b>{{.Post}}{{end}}</pre>
    {{end}}
      </div>
  {{end}}
</body>
</html>
`,

	"repolist": `<html>
  <head>
    <title>Repo search result for {{.Last.Query}}</title>
  </head>
<body>
{{template "searchbox" .Last}}
 <hr>
  Found {{.RepoCount}} repositories:
  <p>
  {{range .Repos}}
    <li>
      <tt>{{if .URL}}<a href="{{.URL}}">{{end}}{{.Name}}{{if .URL}}</a>{{end}}
      </tt> (<small>{{.IndexTime.Format "Jan 02, 2006 15:04"}}</small>). Branches:
      {{range .Branches}}
         {{if .URL}}<a href="{{.URL}}">{{end}}{{.Name}}{{if .URL}}</a>{{end}},
      {{end}}
      <small>{{HumanUnit .Files}} files ({{HumanUnit .Size}})</small>
   </li>
  {{end}}
  </ul>
</body>
</html>
`,

	"print": `
<html>
  <head>
    <title>{{.Repo}}:{{.Name}}</title>
  </head>
<body>{{template "searchbox" .Last}}
<hr>
<p>
  <tt>{{.Repo}} : {{.Name}}</tt>
</p>


<div style="background: #eef;">
<pre>{{.Content}}
</pre>
</div>
</body>
</html>
`,

	"about": `
  <head>
    <title>About <em>zoekt</em></title>
  </head>
<body>

<p>
  This is <a href="http://github.com/google/zoekt"><em>zoekt</em></a>,
  an open-source full text search engine.
</p>

<p>
Used {{HumanUnit .Stats.IndexBytes}} memory for
{{.Stats.Documents}} documents ({{HumanUnit .Stats.ContentBytes}})
from {{.Stats.Repos}} repositories.
</p>

<p>

{{if .Version}}<em>Zoekt</em> version {{.Version}}, uptime{{else}}Uptime{{end}} {{.Uptime}}

</p>
`,
}

func init() {
	for k, v := range TemplateText {
		_, err := Top.New(k).Parse(v)
		if err != nil {
			log.Panicf("parse(%s): %v:", k, err)
		}
	}
}
