// Copyright 2015 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.

// +build appengine

// Package proxy proxies requests to the sandbox compiler service and the
// playground share handler.
// It is designed to run only on the instance of godoc that serves golang.org.
package proxy

import (
	"bytes"
	"crypto/sha1"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strings"
	"time"

	"golang.org/x/net/context"

	"google.golang.org/appengine"
	"google.golang.org/appengine/log"
	"google.golang.org/appengine/memcache"
	"google.golang.org/appengine/urlfetch"
)

type Request struct {
	Body string
}

type Response struct {
	Errors string
	Events []Event
}

type Event struct {
	Message string
	Kind    string        // "stdout" or "stderr"
	Delay   time.Duration // time to wait before printing Message
}

const (
	// We need to use HTTP here for "reasons", but the traffic isn't
	// sensitive and it only travels across Google's internal network
	// so we should be OK.
	sandboxURL    = "http://sandbox.golang.org/compile"
	playgroundURL = "https://play.golang.org"
)

const expires = 7 * 24 * time.Hour // 1 week
var cacheControlHeader = fmt.Sprintf("public, max-age=%d", int(expires.Seconds()))

func RegisterHandlers(mux *http.ServeMux) {
	mux.HandleFunc("/compile", compile)
	mux.HandleFunc("/share", share)
}

func compile(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "I only answer to POST requests.", http.StatusMethodNotAllowed)
		return
	}

	c := appengine.NewContext(r)

	body := r.FormValue("body")
	res := &Response{}
	key := cacheKey(body)
	if _, err := memcache.Gob.Get(c, key, res); err != nil {
		if err != memcache.ErrCacheMiss {
			log.Errorf(c, "getting response cache: %v", err)
		}

		req := &Request{Body: body}
		if err := makeSandboxRequest(c, req, res); err != nil {
			log.Errorf(c, "compile error: %v", err)
			http.Error(w, "Internal Server Error", http.StatusInternalServerError)
			return
		}

		item := &memcache.Item{Key: key, Object: res}
		if err := memcache.Gob.Set(c, item); err != nil {
			log.Errorf(c, "setting response cache: %v", err)
		}
	}

	expiresTime := time.Now().Add(expires).UTC()
	w.Header().Set("Expires", expiresTime.Format(time.RFC1123))
	w.Header().Set("Cache-Control", cacheControlHeader)

	var out interface{}
	switch r.FormValue("version") {
	case "2":
		out = res
	default: // "1"
		out = struct {
			CompileErrors string `json:"compile_errors"`
			Output        string `json:"output"`
		}{res.Errors, flatten(res.Events)}
	}
	if err := json.NewEncoder(w).Encode(out); err != nil {
		log.Errorf(c, "encoding response: %v", err)
	}
}

// makeSandboxRequest sends the given Request to the sandbox
// and stores the response in the given Response.
func makeSandboxRequest(c context.Context, req *Request, res *Response) error {
	reqJ, err := json.Marshal(req)
	if err != nil {
		return fmt.Errorf("marshalling request: %v", err)
	}
	r, err := urlfetch.Client(c).Post(sandboxURL, "application/json", bytes.NewReader(reqJ))
	if err != nil {
		return fmt.Errorf("making request: %v", err)
	}
	defer r.Body.Close()
	if r.StatusCode != http.StatusOK {
		b, _ := ioutil.ReadAll(r.Body)
		return fmt.Errorf("bad status: %v body:\n%s", r.Status, b)
	}
	err = json.NewDecoder(r.Body).Decode(res)
	if err != nil {
		return fmt.Errorf("unmarshalling response: %v", err)
	}
	return nil
}

// flatten takes a sequence of Events and returns their contents, concatenated.
func flatten(seq []Event) string {
	var buf bytes.Buffer
	for _, e := range seq {
		buf.WriteString(e.Message)
	}
	return buf.String()
}

func cacheKey(body string) string {
	h := sha1.New()
	io.WriteString(h, body)
	return fmt.Sprintf("prog-%x", h.Sum(nil))
}

func share(w http.ResponseWriter, r *http.Request) {
	if googleCN(r) {
		http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
		return
	}
	target, _ := url.Parse(playgroundURL)
	p := httputil.NewSingleHostReverseProxy(target)
	p.Transport = &urlfetch.Transport{Context: appengine.NewContext(r)}
	p.ServeHTTP(w, r)
}

func googleCN(r *http.Request) bool {
	if r.FormValue("googlecn") != "" {
		return true
	}
	if appengine.IsDevAppServer() {
		return false
	}
	if strings.HasSuffix(r.Host, ".cn") {
		return true
	}
	switch r.Header.Get("X-AppEngine-Country") {
	case "", "ZZ", "CN":
		return true
	}
	return false
}
