package webui

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

// TestAddSenderEmailAlwaysMatchesSelectedDomain guards against the bug where the
// sender's email was a free-text field independent of the selected domain, so a
// sender like bob@gogl.as could be filed under an unrelated domain (e.g.
// freebede.com). The email must always be <local_part>@<the domain actually
// selected>, never whatever the client sends in an email-shaped field.
func TestAddSenderEmailAlwaysMatchesSelectedDomain(t *testing.T) {
	app := newTestApp(t)
	mux := app.Mux()
	cookie := loginSession(t, app)

	domains, err := app.DB.ListDomains()
	if err != nil || len(domains) == 0 {
		t.Fatalf("expected seeded domain: %v", err)
	}
	realDomain := domains[0]

	form := url.Values{
		"local_part": {"bob"},
		"domain_id":  {strconv.FormatInt(realDomain.ID, 10)},
		"password":   {"password123"},
	}
	req := httptest.NewRequest(http.MethodPost, Prefix+"/senders/add", strings.NewReader(form.Encode()))
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.AddCookie(cookie)
	rec := httptest.NewRecorder()
	mux.ServeHTTP(rec, req)
	if rec.Code != http.StatusFound {
		t.Fatalf("expected redirect after adding sender, got %d: %s", rec.Code, rec.Body.String())
	}

	sender, err := app.DB.GetSenderByEmail("bob@" + realDomain.DomainName)
	if err != nil || sender == nil {
		t.Fatalf("expected sender bob@%s to exist: %v", realDomain.DomainName, err)
	}
	if sender.DomainID != realDomain.ID {
		t.Fatalf("sender domain_id = %d, want %d (the domain actually selected)", sender.DomainID, realDomain.ID)
	}

	// A local part that isn't a bare identifier (e.g. tries to smuggle a different
	// domain) must be rejected rather than silently accepted.
	badForm := url.Values{
		"local_part": {"mallory@evil.example"},
		"domain_id":  {strconv.FormatInt(realDomain.ID, 10)},
		"password":   {"password123"},
	}
	badReq := httptest.NewRequest(http.MethodPost, Prefix+"/senders/add", strings.NewReader(badForm.Encode()))
	badReq.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	badReq.AddCookie(cookie)
	badRec := httptest.NewRecorder()
	mux.ServeHTTP(badRec, badReq)

	if s, _ := app.DB.GetSenderByEmail("mallory@evil.example"); s != nil {
		t.Fatal("a local part containing '@' must never produce a sender at an arbitrary domain")
	}
}
