package search

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

func TestParseSearchRequest_MissingQ(t *testing.T) {
	r := httptest.NewRequest(http.MethodGet, "/search?format=json", nil)
	_, err := ParseSearchRequest(r)
	if err == nil {
		t.Fatalf("expected error, got nil")
	}
}

func TestParseSearchRequest_InvalidPageno(t *testing.T) {
	r := httptest.NewRequest(http.MethodGet, "/search?q=hi&pageno=0", nil)
	_, err := ParseSearchRequest(r)
	if err == nil {
		t.Fatalf("expected error for pageno, got nil")
	}
}

func TestParseSearchRequest_InvalidLanguage(t *testing.T) {
	r := httptest.NewRequest(http.MethodGet, "/search?q=hi&language=bad!", nil)
	_, err := ParseSearchRequest(r)
	if err == nil {
		t.Fatalf("expected error for language, got nil")
	}
}

func TestParseSearchRequest_CategoriesAndEngineData(t *testing.T) {
	values := url.Values{}
	values.Set("q", "hello")
	values.Set("format", "json")
	values.Set("categories", "general,science")
	values.Set("category_science", "off")
	values.Set("engines", "wikipedia,arxiv")
	values.Set("engine_data-wikipedia-timeout", "123")

	r := httptest.NewRequest(http.MethodPost, "/search", strings.NewReader(values.Encode()))
	r.Header.Set("Content-Type", "application/x-www-form-urlencoded")

	req, err := ParseSearchRequest(r)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	// categories should drop `science` due to category_science=off
	wantCats := map[string]bool{"general": true}
	gotCats := map[string]bool{}
	for _, c := range req.Categories {
		gotCats[c] = true
	}
	for c := range wantCats {
		if !gotCats[c] {
			t.Fatalf("expected category %q in result, got %v", c, req.Categories)
		}
	}
	if gotCats["science"] {
		t.Fatalf("expected category science to be removed, got %v", req.Categories)
	}

	if len(req.Engines) != 2 {
		t.Fatalf("expected 2 engines, got %v", req.Engines)
	}
	if req.EngineData["wikipedia"]["timeout"] != "123" {
		t.Fatalf("expected engine_data parsed, got %#v", req.EngineData)
	}
}

