package main

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

// Tests valid and invalid URLs via 'validateURL'.
func TestValidateURL(t *testing.T) {
	urls_valid := []string{
		"http://www.bar.com",
		"https://86.31.3.9.de",
		"http://localhost:8080",
		"https://baz.org",
	}

	urls_invalid := []string{
		"http:/www.bar.com",
		"ftp://86.31.3.9.de",
		"localhost:8080",
		"ssh://foo.bar",
	}

	for _, url := range urls_valid {
		err := validateURL(url)
		if err != nil {
			t.Errorf("URL %s invalid\nError was: %s", url, err)
		}
	}

	for _, url := range urls_invalid {
		err := validateURL(url)
		if err == nil {
			t.Errorf("URL %s valid", url)
		}
	}
}

// Tests specific JSON that is accepted by 'parseJson', e.g.
//     {"Numbers": [1,2,5]}
func TestParseJson(t *testing.T) {
	validJSON := [][]byte{
		[]byte("{\"Numbers\": []}"),
		[]byte("{\"Numbers\": [7]}"),
		[]byte("{\"Numbers\": [1,2,5]}"),
		[]byte("{\"Numbers\" : [1 , 2  ,5]}"),
	}

	invalidJSON := [][]byte{
		[]byte("{\"Numbers\": [}"),
		[]byte("\"Numbers\": [7]}"),
		[]byte("{\"umbers\": [1,2,5]}"),
		[]byte("{\"umbers\": [1,2,5]"),
		[]byte("{\"Numbers\" [1,2,5]}"),
	}

	for _, json := range validJSON {
		_, err := parseJson(json)
		if err != nil {
			t.Errorf("JSON \"%s\" invalid\nError was: %s", json, err)
		}
	}

	for _, json := range invalidJSON {
		res, err := parseJson(json)
		if err == nil {
			t.Errorf("JSON \"%s\" valid\nResult was: %s", json, res)
		}
	}
}

// Test the actual backend handler. Because we have no mocking framework,
// we just do a few very basic tests.
func TestHandler(t *testing.T) {
	// no url parameters => status code 400
	{
		req, err := http.NewRequest("GET", "/numbers", nil)
		if err != nil {
			t.Fatal(err)
		}

		rr := httptest.NewRecorder()
		handler := http.HandlerFunc(numbersHandler)
		handler.ServeHTTP(rr, req)

		if status := rr.Code; status != http.StatusBadRequest {
			t.Errorf("Handler returned status code %v, expected %v", status, http.StatusOK)
		}
	}

	// invalid url => empty result, status code 200
	{
		req, err := http.NewRequest("GET", "/numbers?u=ftp://a.b.c.d.e.f", nil)
		if err != nil {
			t.Fatal(err)
		}

		rr := httptest.NewRecorder()
		handler := http.HandlerFunc(numbersHandler)
		handler.ServeHTTP(rr, req)

		if status := rr.Code; status != http.StatusOK {
			t.Errorf("Handler returned status code %v, expected %v", status, http.StatusOK)
		}
		body := rr.Body.String()
		expected := "{\"Numbers\":[]}\n"
		if body != expected {
			t.Errorf("Body not as expected, got %s, expected %s", body, expected)
		}
	}
}