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

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

	"golang.org/x/website/internal/web"
)

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

type Request struct {
	Body    string
	WithVet bool
}

type Response struct {
	Errors    string
	Events    []Event
	VetErrors string
}

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 the playground endpoints.
func RegisterHandlers(mux *http.ServeMux, godevSite, chinaSite *web.Site) {
	mux.Handle("/play/", playHandler(godevSite))
	mux.Handle("golang.google.cn/play/", playHandler(chinaSite))
	for _, host := range []string{"golang.org", "go.dev/_", "golang.google.cn/_"} {
		mux.HandleFunc(host+"/compile", compile)
		if host != "golang.google.cn" {
			mux.HandleFunc(host+"/share", share)
		}
		mux.HandleFunc(host+"/fmt", fmtHandler)
	}
}

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")
	withVet := r.FormValue("withVet")
	res := &Response{}
	req := &Request{Body: body, WithVet: withVet == "true"}
	if err := makeCompileRequest(ctx, backend(r), req, res); err != nil {
		log.Printf("ERROR compile error %s: %v", backend(r), 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)
}

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

	client := &http.Client{
		Timeout: 20 * time.Second,
	}
	r, err := client.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("unmarshaling 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()
}

var validID = regexp.MustCompile(`^[A-Za-z0-9_\-]+$`)

func share(w http.ResponseWriter, r *http.Request) {
	if id := r.FormValue("id"); r.Method == "GET" && validID.MatchString(id) {
		simpleProxy(w, r, playgroundURL+"/p/"+id+".go")
		return
	}

	simpleProxy(w, r, playgroundURL+"/share")
}

func fmtHandler(w http.ResponseWriter, r *http.Request) {
	simpleProxy(w, r, "https://"+backend(r)+"/fmt")
}

func simpleProxy(w http.ResponseWriter, r *http.Request, url string) {
	if r.Method == "GET" {
		r.Body = nil
	} else if len(r.Form) > 0 {
		r.Body = io.NopCloser(strings.NewReader(r.Form.Encode()))
	}
	req, _ := http.NewRequest(r.Method, url, 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)
}

func backend(r *http.Request) string {
	b := r.URL.Query().Get("backend")
	if !isDomainElem(b) {
		return "play.golang.org"
	}
	return b + "play.golang.org"
}

func isDomainElem(s string) bool {
	for i := 0; i < len(s); i++ {
		if !('a' <= s[i] && s[i] <= 'z' || '0' <= s[i] && s[i] <= '9') {
			return false
		}
	}
	return s != ""
}
