// 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 _, pattern := range []string{"golang.org", "go.dev/_", "golang.google.cn/_"} {
		mux.HandleFunc(pattern+"/compile", compile)
		if pattern != "golang.google.cn/_" {
			mux.HandleFunc(pattern+"/share", share)
		}
		mux.HandleFunc(pattern+"/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 != ""
}
