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

// Package proxy proxies requests to the playground's compile and share handlers.
// It is designed to run only on the instance of godoc that serves golang.org.
package proxy

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"time"
)

const playgroundURL = "https://play.golang.org"

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 expires = 7 * 24 * time.Hour // 1 week
var cacheControlHeader = fmt.Sprintf("public, max-age=%d", int(expires.Seconds()))

// RegisterHandlers registers handlers
// for golang.org/compile and golang.org/share on mux.
// If disallow is non-nil, then the share handler disallows requests
// for which disallowShare returns true.
func RegisterHandlers(mux *http.ServeMux, disallowShare func(*http.Request) bool) {
	mux.HandleFunc("golang.org/compile", compile)
	mux.HandleFunc("golang.org/share", share(disallowShare))
}

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

	ctx := r.Context()

	body := r.FormValue("body")
	res := &Response{}
	req := &Request{Body: body}
	if err := makeCompileRequest(ctx, req, res); err != nil {
		log.Printf("ERROR compile error: %v", err)
		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
		return
	}

	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)}
	}
	b, err := json.Marshal(out)
	if err != nil {
		log.Printf("ERROR encoding response: %v", err)
		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
		return
	}

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

// makePlaygroundRequest sends the given Request to the playground compile
// endpoint and stores the response in the given Response.
func makeCompileRequest(ctx context.Context, req *Request, res *Response) error {
	reqJ, err := json.Marshal(req)
	if err != nil {
		return fmt.Errorf("marshalling request: %v", err)
	}
	hReq, _ := http.NewRequest("POST", playgroundURL+"/compile", bytes.NewReader(reqJ))
	hReq.Header.Set("Content-Type", "application/json")
	hReq = hReq.WithContext(ctx)

	r, err := http.DefaultClient.Do(hReq)
	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)
	}

	if err := json.NewDecoder(r.Body).Decode(res); 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 share(disallow func(*http.Request) bool) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if disallow != nil && disallow(r) {
			http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
			return
		}

		// HACK(cbro): use a simple proxy rather than httputil.ReverseProxy because of Issue #28168.
		// TODO: investigate using ReverseProxy with a Director, unsetting whatever's necessary to make that work.
		req, _ := http.NewRequest("POST", playgroundURL+"/share", r.Body)
		req.Header.Set("Content-Type", r.Header.Get("Content-Type"))
		req = req.WithContext(r.Context())
		resp, err := http.DefaultClient.Do(req)
		if err != nil {
			log.Printf("ERROR share error: %v", err)
			http.Error(w, "Internal Server Error", http.StatusInternalServerError)
			return
		}
		copyHeader := func(k string) {
			if v := resp.Header.Get(k); v != "" {
				w.Header().Set(k, v)
			}
		}
		copyHeader("Content-Type")
		copyHeader("Content-Length")
		defer resp.Body.Close()
		w.WriteHeader(resp.StatusCode)
		io.Copy(w, resp.Body)
	}
}
