package main

import (
	"net/http/httptest"
	"strings"
	"testing"

	"github.com/peter-evans/patience"
)

func newHandler() handler {
	return handler{
		domain: "lex.example",
		countries: map[string]country{
			"zu": country{
				Name:      "Zubrowka",
				SearchURL: "https://lex.gov.zu/?search=%s",
			},
		},
		lawsByCC: map[string]map[string]law{},
	}
}

func TestStartPage(t *testing.T) {
	h := newHandler()

	req := httptest.NewRequest("GET", "/", nil)
	req.Host = "lex.example"
	w := httptest.NewRecorder()
	h.handle(w, req)

	resp := w.Result()
	if resp.StatusCode != 200 {
		t.Errorf("expected status 200 OK, got %d", resp.StatusCode)
	}
	expected := `<!doctype html>
<html>
<head>
	<title>Lex.surf: Portal to National Law</title>
	<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
	<link rel="stylesheet" href="/assets/style.css" />
</head>
<body>
	<img alt="lex.surf" height=140 class=logo src="/assets/logo.svg">
	<h2>The portal to&nbsp;national&nbsp;law.</h2>
	<div class=countries>
	<a class=cc-link href="//zu.lex.example" title="Zubrowka">ZU</a>
	</div>
</body>
</html>
`
	assertEqual(t, w.Body.String(), expected)
}

func TestSearch(t *testing.T) {
	h := newHandler()

	req := httptest.NewRequest("GET", "/", nil)
	req.Host = "zu.lex.example"
	w := httptest.NewRecorder()
	h.handle(w, req)

	resp := w.Result()
	if resp.StatusCode != 200 {
		t.Errorf("expected status 200 OK, got %d", resp.StatusCode)
	}
	expected := `<!doctype html>
<html>
<head>
	<title>National Law of Zubrowka</title>
	<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
	<link rel="stylesheet" href="//lex.example/assets/style.css" />
</head>
<body>
	<a href="//lex.example"><img alt="lex.surf" height=140 class=logo src="//lex.example/assets/logo.svg"></a>
	<h1>National Law of Zubrowka</h1>
	
	
		<form>
	
	
		<input id=search name=q aria-label="Search" autocomplete="off" autofocus >
		<ul id=suggestions></ul>
	
	
		</form>
	
	<script src="//lex.example/assets/script.js"></script>
</body>
</html>
`
	assertEqual(t, w.Body.String(), expected)
}

func TestSearchRedirect(t *testing.T) {
	h := newHandler()

	req := httptest.NewRequest("GET", "/?q=tourism", nil)
	req.Host = "zu.lex.example"
	w := httptest.NewRecorder()
	h.handle(w, req)

	resp := w.Result()
	if resp.StatusCode != 302 {
		t.Errorf("expected status 302, got %d", resp.StatusCode)
	}

	if resp.Header.Get("Location") != "https://lex.gov.zu/?search=tourism" {
		t.Errorf("wrong location, got %s", resp.Header.Get("Location"))
	}
}

func TestLawRedirect(t *testing.T) {
	h := newHandler()

	h.lawsByCC["zu"] = map[string]law{}
	h.lawsByCC["zu"]["zepl"] = law{
		URL: "https://lex.gov.zu/zeppelin-code",
	}

	req := httptest.NewRequest("GET", "/zepl", nil)
	req.Host = "zu.lex.example"
	w := httptest.NewRecorder()
	h.handle(w, req)

	resp := w.Result()
	if resp.StatusCode != 302 {
		t.Errorf("expected status 302, got %d", resp.StatusCode)
	}

	if resp.Header.Get("Location") != "https://lex.gov.zu/zeppelin-code" {
		t.Errorf("wrong location, got %s", resp.Header.Get("Location"))
	}
}

func assertEqual(t *testing.T, received string, expected string) {
	if received != expected {
		a := strings.Split(received, "\n")
		b := strings.Split(expected, "\n")
		diffs := patience.Diff(a, b)
		unidiff := patience.UnifiedDiffText(diffs)
		t.Error(unidiff)
	}
}