// Copyright 2018 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 owners

import (
	"bytes"
	"encoding/json"
	"html/template"
	"log"
	"net/http"
)

type Owner struct {
	GitHubUsername string `json:"githubUsername"`
	GerritEmail    string `json:"gerritEmail"`
}

type Entry struct {
	Primary   []Owner `json:"primary"`
	Secondary []Owner `json:"secondary,omitempty"`
}

type Request struct {
	Payload struct {
		Paths []string `json:"paths"`
	} `json:"payload"`
	Version int `json:"v"` // API version
}

type Response struct {
	Payload struct {
		Entries map[string]*Entry `json:"entries"` // paths in request -> Entry
	} `json:"payload"`
	Error string `json:"error,omitempty"`
}

// match takes a path consisting of the repo name and full path of a file or
// directory within that repo and returns the deepest Entry match in the file
// hierarchy for the given resource.
func match(path string) *Entry {
	var deepestPath string
	for p := range entries {
		if hasPathPrefix(path, p) && len(p) > len(deepestPath) {
			deepestPath = p
		}
	}
	return entries[deepestPath]
}

// hasPathPrefix reports whether the slash-separated path s
// begins with the elements in prefix.
//
// Copied from go/src/cmd/go/internal/str.HasPathPrefix.
func hasPathPrefix(s, prefix string) bool {
	if len(s) == len(prefix) {
		return s == prefix
	}
	if prefix == "" {
		return true
	}
	if len(s) > len(prefix) {
		if prefix[len(prefix)-1] == '/' || s[len(prefix)] == '/' {
			return s[:len(prefix)] == prefix
		}
	}
	return false
}

// Handler takes one or more paths and returns a map of each to a matching
// Entry struct. If no Entry is matched for the path, the value for the key
// is nil.
func Handler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Content-Type", "application/json")

	switch r.Method {
	case "GET":
		serveIndex(w, r)
		return
	case "POST":
		var req Request
		if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
			jsonError(w, "unable to decode request", http.StatusBadRequest)
			// TODO: increment expvar for monitoring.
			log.Printf("unable to decode owners request: %v", err)
			return
		}

		var resp Response
		resp.Payload.Entries = make(map[string]*Entry)
		for _, p := range req.Payload.Paths {
			resp.Payload.Entries[p] = match(p)
		}
		var buf bytes.Buffer
		if err := json.NewEncoder(&buf).Encode(resp); err != nil {
			jsonError(w, "unable to encode response", http.StatusInternalServerError)
			// TODO: increment expvar for monitoring.
			log.Printf("unable to encode owners response: %v", err)
			return
		}
		w.Write(buf.Bytes())
	case "OPTIONS":
		// Likely a CORS preflight request; leave resp.Payload empty.
	default:
		jsonError(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
		return
	}
}

func jsonError(w http.ResponseWriter, text string, code int) {
	w.WriteHeader(code)
	var buf bytes.Buffer
	if err := json.NewEncoder(&buf).Encode(Response{Error: text}); err != nil {
		// TODO: increment expvar for monitoring.
		log.Printf("unable to encode error response: %v", err)
		return
	}
	w.Write(buf.Bytes())
}

func serveIndex(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")

	var buf bytes.Buffer
	if err := indexTmpl.Execute(&buf, entries); err != nil {
		log.Printf("unable to execute index template: %v", err)
		http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		return
	}
	w.Write(buf.Bytes())
}

var indexTmpl = template.Must(template.New("index").Parse(`<!DOCTYPE html>
<html lang="en">
<title>Go Code Owners</title>
<meta name=viewport content="width=device-width, initial-scale=1">
<style>
* {
	box-sizing: border-box;
	margin: 0;
	padding: 0;
}
body {
	font-family: sans-serif;
	margin: 1rem 1.5rem;
}
.header {
	color: #666;
	font-size: 90%;
	margin-bottom: 1rem;
}
.table-header {
	font-weight: bold;
	position: sticky;
	top: 0;
}
.table-header,
.entry {
	background-color: #fff;
	border-bottom: 1px solid #ddd;
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	margin: .15rem 0;
	padding: .15rem 0;
}
.path,
.primary,
.secondary {
	flex-basis: 33.3%;
}
</style>
<header class="header">
	Alter these entries at
	<a href="https://go.googlesource.com/build/+/master/devapp/owners"
		target="_blank" rel="noopener">golang.org/x/build/devapp/owners</a>
</header>
<main>
<div class="table-header">
	<span class="path">Path</span>
	<span class="primary">Primaries</span>
	<span class="secondary">Secondaries</span>
</div>
{{range $path, $entry := .}}
	<div class="entry">
		<span class="path">{{$path}}</span>
		<span class="primary">
			{{range .Primary}}
				<a href="https://github.com/{{.GitHubUsername}}" target="_blank" rel="noopener">@{{.GitHubUsername}}</a>
			{{end}}
		</span>
		<span class="secondary">
			{{range .Secondary}}
				<a href="https://github.com/{{.GitHubUsername}}" target="_blank" rel="noopener">@{{.GitHubUsername}}</a>
			{{end}}
		</span>
	</div>
{{end}}
</main>
`))
