// 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"
	"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},
	}

	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
}
