// Copyright 2017 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 main

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"os"
	"runtime"
	"sync"
	"testing"
	"time"

	"github.com/bradfitz/gomemcache/memcache"
	"github.com/google/go-cmp/cmp"
)

type testLogger struct {
	t *testing.T
}

func (l testLogger) Printf(format string, args ...interface{}) {
	l.t.Logf(format, args...)
}
func (l testLogger) Errorf(format string, args ...interface{}) {
	l.t.Errorf(format, args...)
}
func (l testLogger) Fatalf(format string, args ...interface{}) {
	l.t.Fatalf(format, args...)
}

func testingOptions(t *testing.T) func(s *server) error {
	return func(s *server) error {
		s.db = &inMemStore{}
		s.log = testLogger{t}
		var err error
		s.examples, err = newExamplesHandler(false, time.Now())
		if err != nil {
			return err
		}
		return nil
	}
}

func TestEdit(t *testing.T) {
	s, err := newServer(testingOptions(t))
	if err != nil {
		t.Fatalf("newServer(testingOptions(t)): %v", err)
	}
	id := "bar"
	barBody := []byte("Snippy McSnipface")
	snip := &snippet{Body: barBody}
	if err := s.db.PutSnippet(context.Background(), id, snip); err != nil {
		t.Fatalf("s.dbPutSnippet(context.Background(), %+v, %+v): %v", id, snip, err)
	}

	testCases := []struct {
		desc       string
		method     string
		url        string
		statusCode int
		headers    map[string]string
		respBody   []byte
	}{
		{"OPTIONS no-op", http.MethodOptions, "https://play.golang.org/p/foo", http.StatusOK, nil, nil},
		{"foo.play.golang.org to play.golang.org", http.MethodGet, "https://foo.play.golang.org", http.StatusFound, map[string]string{"Location": "https://play.golang.org"}, nil},
		{"Non-existent page", http.MethodGet, "https://play.golang.org/foo", http.StatusNotFound, nil, nil},
		{"Unknown snippet", http.MethodGet, "https://play.golang.org/p/foo", http.StatusNotFound, nil, nil},
		{"Existing snippet", http.MethodGet, "https://play.golang.org/p/" + id, http.StatusFound, nil, nil},
		{"Plaintext snippet", http.MethodGet, "https://play.golang.org/p/" + id + ".go", http.StatusOK, nil, barBody},
		{"Download snippet", http.MethodGet, "https://play.golang.org/p/" + id + ".go?download=true", http.StatusOK, map[string]string{"Content-Disposition": fmt.Sprintf(`attachment; filename="%s.go"`, id)}, barBody},
	}

	for _, tc := range testCases {
		req := httptest.NewRequest(tc.method, tc.url, nil)
		w := httptest.NewRecorder()
		s.handleEdit(w, req)
		resp := w.Result()
		corsHeader := "Access-Control-Allow-Origin"
		if got, want := resp.Header.Get(corsHeader), "*"; got != want {
			t.Errorf("%s: %q header: got %q; want %q", tc.desc, corsHeader, got, want)
		}
		if got, want := resp.StatusCode, tc.statusCode; got != want {
			t.Errorf("%s: got unexpected status code %d; want %d", tc.desc, got, want)
		}
		for k, v := range tc.headers {
			if got, want := resp.Header.Get(k), v; got != want {
				t.Errorf("Got header value %q of %q; want %q", k, got, want)
			}
		}
		if tc.respBody != nil {
			defer resp.Body.Close()
			b, err := ioutil.ReadAll(resp.Body)
			if err != nil {
				t.Errorf("%s: ioutil.ReadAll(resp.Body): %v", tc.desc, err)
			}
			if !bytes.Equal(b, tc.respBody) {
				t.Errorf("%s: got unexpected body %q; want %q", tc.desc, b, tc.respBody)
			}
		}
	}
}

func TestServer(t *testing.T) {
	s, err := newServer(testingOptions(t))
	if err != nil {
		t.Fatalf("newServer(testingOptions(t)): %v", err)
	}

	const shareURL = "https://play.golang.org/share"
	testCases := []struct {
		desc       string
		method     string
		url        string
		statusCode int
		reqBody    []byte
		respBody   []byte
	}{
		// Share tests.
		{"OPTIONS no-op", http.MethodOptions, shareURL, http.StatusOK, nil, nil},
		{"Non-POST request", http.MethodGet, shareURL, http.StatusMethodNotAllowed, nil, nil},
		{"Standard flow", http.MethodPost, shareURL, http.StatusOK, []byte("Snippy McSnipface"), []byte("N_M_YelfGeR")},
		{"Snippet too large", http.MethodPost, shareURL, http.StatusRequestEntityTooLarge, make([]byte, maxSnippetSize+1), nil},

		// Examples tests.
		{"Hello example", http.MethodGet, "https://play.golang.org/doc/play/hello.txt", http.StatusOK, nil, []byte("Hello")},
		{"HTTP example", http.MethodGet, "https://play.golang.org/doc/play/http.txt", http.StatusOK, nil, []byte("net/http")},
		// Gotip examples should not be available on the non-tip playground.
		{"Gotip example", http.MethodGet, "https://play.golang.org/doc/play/min.gotip.txt", http.StatusNotFound, nil, nil},

		{"Versions json", http.MethodGet, "https://play.golang.org/version", http.StatusOK, nil, []byte(runtime.Version())},
	}

	for _, tc := range testCases {
		req := httptest.NewRequest(tc.method, tc.url, bytes.NewReader(tc.reqBody))
		w := httptest.NewRecorder()
		s.mux.ServeHTTP(w, req)
		resp := w.Result()
		corsHeader := "Access-Control-Allow-Origin"
		if got, want := resp.Header.Get(corsHeader), "*"; got != want {
			t.Errorf("%s: %q header: got %q; want %q", tc.desc, corsHeader, got, want)
		}
		if got, want := resp.StatusCode, tc.statusCode; got != want {
			t.Errorf("%s: got unexpected status code %d; want %d", tc.desc, got, want)
		}
		if tc.respBody != nil {
			defer resp.Body.Close()
			b, err := ioutil.ReadAll(resp.Body)
			if err != nil {
				t.Errorf("%s: ioutil.ReadAll(resp.Body): %v", tc.desc, err)
			}
			if !bytes.Contains(b, tc.respBody) {
				t.Errorf("%s: got unexpected body %q; want contains %q", tc.desc, b, tc.respBody)
			}
		}
	}
}

func TestNoTrailingUnderscore(t *testing.T) {
	const trailingUnderscoreSnip = `package main

import "unsafe"

type T struct{}

func (T) m1()                         {}
func (T) m2([unsafe.Sizeof(T.m1)]int) {}

func main() {}
`
	snip := &snippet{[]byte(trailingUnderscoreSnip)}
	if got, want := snip.ID(), "WCktUidLyc_3"; got != want {
		t.Errorf("got %q; want %q", got, want)
	}
}

func TestCommandHandler(t *testing.T) {
	s, err := newServer(func(s *server) error {
		s.db = &inMemStore{}
		// testLogger makes tests fail.
		// Should we verify that s.log.Errorf was called
		// instead of just printing or failing the test?
		s.log = newStdLogger()
		s.cache = new(inMemCache)
		var err error
		s.examples, err = newExamplesHandler(false, time.Now())
		if err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		t.Fatalf("newServer(testingOptions(t)): %v", err)
	}
	testHandler := s.commandHandler("test", func(_ context.Context, r *request) (*response, error) {
		if r.Body == "fail" {
			return nil, fmt.Errorf("non recoverable")
		}
		if r.Body == "error" {
			return &response{Errors: "errors"}, nil
		}
		if r.Body == "oom-error" {
			// To throw an oom in a local playground instance, increase the server timeout
			// to 20 seconds (within sandbox.go), spin up the Docker instance and run
			// this code: https://play.golang.org/p/aaCv86m0P14.
			return &response{Events: []Event{{"out of memory", "stderr", 0}}}, nil
		}
		if r.Body == "allocate-memory-error" {
			return &response{Events: []Event{{"cannot allocate memory", "stderr", 0}}}, nil
		}
		if r.Body == "oom-compile-error" {
			return &response{Errors: "out of memory"}, nil
		}
		if r.Body == "allocate-memory-compile-error" {
			return &response{Errors: "cannot allocate memory"}, nil
		}
		if r.Body == "build-timeout-error" {
			return &response{Errors: goBuildTimeoutError}, nil
		}
		if r.Body == "run-timeout-error" {
			return &response{Errors: runTimeoutError}, nil
		}
		resp := &response{Events: []Event{{r.Body, "stdout", 0}}}
		return resp, nil
	})

	testCases := []struct {
		desc        string
		method      string
		statusCode  int
		reqBody     []byte
		respBody    []byte
		shouldCache bool
	}{
		{"OPTIONS request", http.MethodOptions, http.StatusOK, nil, nil, false},
		{"GET request", http.MethodGet, http.StatusBadRequest, nil, nil, false},
		{"Empty POST", http.MethodPost, http.StatusBadRequest, nil, nil, false},
		{"Failed cmdFunc", http.MethodPost, http.StatusInternalServerError, []byte(`{"Body":"fail"}`), nil, false},
		{"Standard flow", http.MethodPost, http.StatusOK,
			[]byte(`{"Body":"ok"}`),
			[]byte(`{"Errors":"","Events":[{"Message":"ok","Kind":"stdout","Delay":0}],"Status":0,"IsTest":false,"TestsFailed":0}
`),
			true},
		{"Cache-able Errors in response", http.MethodPost, http.StatusOK,
			[]byte(`{"Body":"error"}`),
			[]byte(`{"Errors":"errors","Events":null,"Status":0,"IsTest":false,"TestsFailed":0}
`),
			true},
		{"Out of memory error in response body event message", http.MethodPost, http.StatusInternalServerError,
			[]byte(`{"Body":"oom-error"}`), nil, false},
		{"Cannot allocate memory error in response body event message", http.MethodPost, http.StatusInternalServerError,
			[]byte(`{"Body":"allocate-memory-error"}`), nil, false},
		{"Out of memory error in response errors", http.MethodPost, http.StatusInternalServerError,
			[]byte(`{"Body":"oom-compile-error"}`), nil, false},
		{"Cannot allocate memory error in response errors", http.MethodPost, http.StatusInternalServerError,
			[]byte(`{"Body":"allocate-memory-compile-error"}`), nil, false},
		{
			desc:       "Build timeout error",
			method:     http.MethodPost,
			statusCode: http.StatusOK,
			reqBody:    []byte(`{"Body":"build-timeout-error"}`),
			respBody:   []byte(fmt.Sprintln(`{"Errors":"timeout running go build","Events":null,"Status":0,"IsTest":false,"TestsFailed":0}`)),
		},
		{
			desc:       "Run timeout error",
			method:     http.MethodPost,
			statusCode: http.StatusOK,
			reqBody:    []byte(`{"Body":"run-timeout-error"}`),
			respBody:   []byte(fmt.Sprintln(`{"Errors":"timeout running program","Events":null,"Status":0,"IsTest":false,"TestsFailed":0}`)),
		},
	}

	for _, tc := range testCases {
		t.Run(tc.desc, func(t *testing.T) {
			req := httptest.NewRequest(tc.method, "/compile", bytes.NewReader(tc.reqBody))
			w := httptest.NewRecorder()
			testHandler(w, req)
			resp := w.Result()
			corsHeader := "Access-Control-Allow-Origin"
			if got, want := resp.Header.Get(corsHeader), "*"; got != want {
				t.Errorf("%s: %q header: got %q; want %q", tc.desc, corsHeader, got, want)
			}
			if got, want := resp.StatusCode, tc.statusCode; got != want {
				t.Errorf("%s: got unexpected status code %d; want %d", tc.desc, got, want)
			}
			if tc.respBody != nil {
				defer resp.Body.Close()
				b, err := ioutil.ReadAll(resp.Body)
				if err != nil {
					t.Errorf("%s: ioutil.ReadAll(resp.Body): %v", tc.desc, err)
				}
				if !bytes.Equal(b, tc.respBody) {
					t.Errorf("%s: got unexpected body %q; want %q", tc.desc, b, tc.respBody)
				}
			}

			// Test caching semantics.
			sbreq := new(request)             // A sandbox request, used in the cache key.
			json.Unmarshal(tc.reqBody, sbreq) // Ignore errors, request may be empty.
			gotCache := new(response)
			if err := s.cache.Get(cacheKey("test", sbreq.Body), gotCache); (err == nil) != tc.shouldCache {
				t.Errorf("s.cache.Get(%q, %v) = %v, shouldCache: %v", cacheKey("test", sbreq.Body), gotCache, err, tc.shouldCache)
			}
			wantCache := new(response)
			if tc.shouldCache {
				if err := json.Unmarshal(tc.respBody, wantCache); err != nil {
					t.Errorf("json.Unmarshal(%q, %v) = %v, wanted no error", tc.respBody, wantCache, err)
				}
			}
			if diff := cmp.Diff(wantCache, gotCache); diff != "" {
				t.Errorf("s.Cache.Get(%q) mismatch (-want +got):\n%s", cacheKey("test", sbreq.Body), diff)
			}
		})
	}
}

func TestPlaygroundGoproxy(t *testing.T) {
	const envKey = "PLAY_GOPROXY"
	defer os.Setenv(envKey, os.Getenv(envKey))

	tests := []struct {
		name string
		env  string
		want string
	}{
		{name: "missing", env: "", want: "https://proxy.golang.org"},
		{name: "set_to_default", env: "https://proxy.golang.org", want: "https://proxy.golang.org"},
		{name: "changed", env: "https://company.intranet", want: "https://company.intranet"},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if tt.env != "" {
				if err := os.Setenv(envKey, tt.env); err != nil {
					t.Errorf("unable to set environment variable for test: %s", err)
				}
			} else {
				if err := os.Unsetenv(envKey); err != nil {
					t.Errorf("unable to unset environment variable for test: %s", err)
				}
			}
			got := playgroundGoproxy()
			if got != tt.want {
				t.Errorf("playgroundGoproxy = %s; want %s; env: %s", got, tt.want, tt.env)
			}
		})
	}
}

// inMemCache is a responseCache backed by a map. It is only suitable for testing.
type inMemCache struct {
	l sync.Mutex
	m map[string]*response
}

// Set implements the responseCache interface.
// Set stores a *response in the cache. It panics for other types to ensure test failure.
func (i *inMemCache) Set(key string, v interface{}) error {
	i.l.Lock()
	defer i.l.Unlock()
	if i.m == nil {
		i.m = make(map[string]*response)
	}
	i.m[key] = v.(*response)
	return nil
}

// Get implements the responseCache interface.
// Get fetches a *response from the cache, or returns a memcache.ErrcacheMiss.
// It panics for other types to ensure test failure.
func (i *inMemCache) Get(key string, v interface{}) error {
	i.l.Lock()
	defer i.l.Unlock()
	target := v.(*response)
	got, ok := i.m[key]
	if !ok {
		return memcache.ErrCacheMiss
	}
	*target = *got
	return nil
}
