// Copyright 2019 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_test

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"testing"
)

func TestSnippetsCompile(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping slow builds in short mode")
	}

	goFiles, err := filepath.Glob("*.go")
	if err != nil {
		t.Fatal(err)
	}

	for _, f := range goFiles {
		if strings.HasSuffix(f, "_test.go") {
			continue
		}
		f := f
		t.Run(f, func(t *testing.T) {
			t.Parallel()

			cmd := exec.Command("go", "build", "-o", os.DevNull, f)
			out, err := cmd.CombinedOutput()
			if err != nil {
				t.Errorf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, out)
			}
		})
	}
}

func TestWikiServer(t *testing.T) {
	must := func(err error) {
		if err != nil {
			t.Helper()
			t.Fatal(err)
		}
	}

	dir, err := os.MkdirTemp("", t.Name())
	must(err)
	defer os.RemoveAll(dir)

	// We're testing a walkthrough example of how to write a server.
	//
	// That server hard-codes a port number to make the walkthrough simpler, but
	// we can't assume that the hard-coded port is available on an arbitrary
	// builder. So we'll patch out the hard-coded port, and replace it with a
	// function that writes the server's address to stdout
	// so that we can read it and know where to send the test requests.

	finalGo, err := os.ReadFile("final.go")
	must(err)
	const patchOld = `log.Fatal(http.ListenAndServe(":8080", nil))`
	patched := bytes.ReplaceAll(finalGo, []byte(patchOld), []byte(`log.Fatal(serve())`))
	if bytes.Equal(patched, finalGo) {
		t.Fatalf("Can't patch final.go: %q not found.", patchOld)
	}
	must(os.WriteFile(filepath.Join(dir, "final_patched.go"), patched, 0644))

	// Build the server binary from the patched sources.
	// The 'go' command requires that they all be in the same directory.
	// final_test.go provides the implementation for our serve function.
	must(copyFile(filepath.Join(dir, "final_srv.go"), "final_test.go"))
	cmd := exec.Command("go", "build",
		"-o", filepath.Join(dir, "final.exe"),
		filepath.Join(dir, "final_patched.go"),
		filepath.Join(dir, "final_srv.go"))
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, out)
	}

	// Run the server in our temporary directory so that it can
	// write its content there. It also needs a couple of template files,
	// and looks for them in the same directory.
	must(copyFile(filepath.Join(dir, "edit.html"), "edit.html"))
	must(copyFile(filepath.Join(dir, "view.html"), "view.html"))
	cmd = exec.Command(filepath.Join(dir, "final.exe"))
	cmd.Dir = dir
	stderr := bytes.NewBuffer(nil)
	cmd.Stderr = stderr
	stdout, err := cmd.StdoutPipe()
	must(err)
	must(cmd.Start())

	defer func() {
		cmd.Process.Kill()
		err := cmd.Wait()
		if stderr.Len() > 0 {
			t.Logf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, stderr)
		}
	}()

	var addr string
	if _, err := fmt.Fscanln(stdout, &addr); err != nil || addr == "" {
		t.Fatalf("Failed to read server address: %v", err)
	}

	// The server is up and has told us its address.
	// Make sure that its HTTP API works as described in the article.

	r, err := http.Get(fmt.Sprintf("http://%s/edit/Test", addr))
	must(err)
	responseMustMatchFile(t, r, "test_edit.good")

	r, err = http.Post(fmt.Sprintf("http://%s/save/Test", addr),
		"application/x-www-form-urlencoded",
		strings.NewReader("body=some%20content"))
	must(err)
	responseMustMatchFile(t, r, "test_view.good")

	gotTxt, err := os.ReadFile(filepath.Join(dir, "Test.txt"))
	must(err)
	wantTxt, err := os.ReadFile("test_Test.txt.good")
	must(err)
	if !bytes.Equal(wantTxt, gotTxt) {
		t.Fatalf("Test.txt differs from expected after posting to /save.\ngot:\n%s\nwant:\n%s", gotTxt, wantTxt)
	}

	r, err = http.Get(fmt.Sprintf("http://%s/view/Test", addr))
	must(err)
	responseMustMatchFile(t, r, "test_view.good")
}

func responseMustMatchFile(t *testing.T, r *http.Response, filename string) {
	t.Helper()

	defer r.Body.Close()
	body, err := io.ReadAll(r.Body)
	if err != nil {
		t.Fatal(err)
	}

	wantBody, err := os.ReadFile(filename)
	if err != nil {
		t.Fatal(err)
	}

	if !bytes.Equal(body, wantBody) {
		t.Fatalf("%v: body does not match %s.\ngot:\n%s\nwant:\n%s", r.Request.URL, filename, body, wantBody)
	}
}

func copyFile(dst, src string) error {
	buf, err := os.ReadFile(src)
	if err != nil {
		return err
	}
	return os.WriteFile(dst, buf, 0644)
}
