// 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 implemtation 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)
}
