// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// +build golangorg

// Package short implements a simple URL shortener, serving an administrative
// interface at /s and shortened urls from /s/key.
// It is designed to run only on the instance of godoc that serves golang.org.
package short

// TODO(adg): collect statistics on URL visits

import (
	"context"
	"errors"
	"fmt"
	"html/template"
	"io"
	"log"
	"net/http"
	"net/url"
	"regexp"

	"cloud.google.com/go/datastore"
	"golang.org/x/tools/internal/memcache"
	"google.golang.org/appengine/user"
)

const (
	prefix  = "/s"
	kind    = "Link"
	baseURL = "https://golang.org" + prefix
)

// Link represents a short link.
type Link struct {
	Key, Target string
}

var validKey = regexp.MustCompile(`^[a-zA-Z0-9-_.]+$`)

type server struct {
	datastore *datastore.Client
	memcache  *memcache.CodecClient
}

func RegisterHandlers(mux *http.ServeMux, dc *datastore.Client, mc *memcache.Client) {
	s := server{dc, mc.WithCodec(memcache.JSON)}
	mux.HandleFunc(prefix+"/", s.linkHandler)

	// TODO(cbro): move storage of the links to a text file in Gerrit.
	// Disable the admin handler until that happens, since GAE Flex doesn't support
	// the "google.golang.org/appengine/user" package.
	// See golang.org/issue/29988 and golang.org/issue/27205#issuecomment-418673218.
	// mux.HandleFunc(prefix, adminHandler)
	mux.HandleFunc(prefix, func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusForbidden)
		io.WriteString(w, "Link creation temporarily unavailable. See golang.org/issue/29988.")
	})
}

// linkHandler services requests to short URLs.
//   http://golang.org/s/key
// It consults memcache and datastore for the Link for key.
// It then sends a redirects or an error message.
func (h server) linkHandler(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	key := r.URL.Path[len(prefix)+1:]
	if !validKey.MatchString(key) {
		http.Error(w, "not found", http.StatusNotFound)
		return
	}

	var link Link
	if err := h.memcache.Get(ctx, cacheKey(key), &link); err != nil {
		k := datastore.NameKey(kind, key, nil)
		err = h.datastore.Get(ctx, k, &link)
		switch err {
		case datastore.ErrNoSuchEntity:
			http.Error(w, "not found", http.StatusNotFound)
			return
		default: // != nil
			log.Printf("ERROR %q: %v", key, err)
			http.Error(w, "internal server error", http.StatusInternalServerError)
			return
		case nil:
			item := &memcache.Item{
				Key:    cacheKey(key),
				Object: &link,
			}
			if err := h.memcache.Set(ctx, item); err != nil {
				log.Printf("WARNING %q: %v", key, err)
			}
		}
	}

	http.Redirect(w, r, link.Target, http.StatusFound)
}

var adminTemplate = template.Must(template.New("admin").Parse(templateHTML))

// adminHandler serves an administrative interface.
func (h server) adminHandler(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	if !user.IsAdmin(ctx) {
		http.Error(w, "forbidden", http.StatusForbidden)
		return
	}

	var newLink *Link
	var doErr error
	if r.Method == "POST" {
		key := r.FormValue("key")
		switch r.FormValue("do") {
		case "Add":
			newLink = &Link{key, r.FormValue("target")}
			doErr = h.putLink(ctx, newLink)
		case "Delete":
			k := datastore.NameKey(kind, key, nil)
			doErr = h.datastore.Delete(ctx, k)
		default:
			http.Error(w, "unknown action", http.StatusBadRequest)
		}
		err := h.memcache.Delete(ctx, cacheKey(key))
		if err != nil && err != memcache.ErrCacheMiss {
			log.Printf("WARNING %q: %v", key, err)
		}
	}

	var links []*Link
	q := datastore.NewQuery(kind).Order("Key")
	if _, err := h.datastore.GetAll(ctx, q, &links); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		log.Printf("ERROR %v", err)
		return
	}

	// Put the new link in the list if it's not there already.
	// (Eventual consistency means that it might not show up
	// immediately, which might be confusing for the user.)
	if newLink != nil && doErr == nil {
		found := false
		for i := range links {
			if links[i].Key == newLink.Key {
				found = true
				break
			}
		}
		if !found {
			links = append([]*Link{newLink}, links...)
		}
		newLink = nil
	}

	var data = struct {
		BaseURL string
		Prefix  string
		Links   []*Link
		New     *Link
		Error   error
	}{baseURL, prefix, links, newLink, doErr}
	if err := adminTemplate.Execute(w, &data); err != nil {
		log.Printf("ERROR adminTemplate: %v", err)
	}
}

// putLink validates the provided link and puts it into the datastore.
func (h server) putLink(ctx context.Context, link *Link) error {
	if !validKey.MatchString(link.Key) {
		return errors.New("invalid key; must match " + validKey.String())
	}
	if _, err := url.Parse(link.Target); err != nil {
		return fmt.Errorf("bad target: %v", err)
	}
	k := datastore.NameKey(kind, link.Key, nil)
	_, err := h.datastore.Put(ctx, k, link)
	return err
}

// cacheKey returns a short URL key as a memcache key.
func cacheKey(key string) string {
	return "link-" + key
}
