package cookies

import (
	"strings"
	"testing"
	"time"

	"github.com/chromedp/cdproto/network"
)

func TestParseNetscape_EditThisCookie(t *testing.T) {
	// EditThisCookie-style export: tab-separated, full columns
	data := `# Netscape HTTP Cookie File
# https://curl.se/docs/http-cookies.html
# This file was generated by EditThisCookie
.github.com	TRUE	/	FALSE	1744329600	_session_id	abc123
.github.com	TRUE	/	TRUE	1744329600	user_session	def456
`

	cookies, err := ParseNetscape(strings.NewReader(data), time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC))
	if err != nil {
		t.Fatalf("ParseNetscape failed: %v", err)
	}

	if len(cookies) != 2 {
		t.Fatalf("expected 2 cookies, got %d", len(cookies))
	}

	// First cookie: non-secure
	c0 := cookies[0]
	if c0.Name != "_session_id" {
		t.Errorf("expected name _session_id, got %s", c0.Name)
	}
	if c0.Value != "abc123" {
		t.Errorf("expected value abc123, got %s", c0.Value)
	}
	if c0.Domain != "github.com" {
		t.Errorf("expected domain github.com, got %s", c0.Domain)
	}
	if c0.Path != "/" {
		t.Errorf("expected path /, got %s", c0.Path)
	}
	if c0.Secure {
		t.Error("expected secure=false")
	}
	if c0.HTTPOnly {
		t.Error("expected httpOnly=false")
	}

	// Second cookie: secure
	c1 := cookies[1]
	if c1.Name != "user_session" {
		t.Errorf("expected name user_session, got %s", c1.Name)
	}
	if !c1.Secure {
		t.Error("expected secure=true")
	}
}

func TestParseNetscape_GetCookiesTxt(t *testing.T) {
	// Get cookies.txt extension export: space-separated
	data := `# Netscape HTTP Cookie File
# https://curl.se/docs/http-cookies.html
# This file was generated by Get cookies.txt
.example.com	TRUE	/	FALSE	0	token	xyz789
.example.com	TRUE	/	TRUE	1800000000	prefs	dark_mode
`

	cookies, err := ParseNetscape(strings.NewReader(data), time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC))
	if err != nil {
		t.Fatalf("ParseNetscape failed: %v", err)
	}

	if len(cookies) != 2 {
		t.Fatalf("expected 2 cookies, got %d", len(cookies))
	}

	// First cookie: session cookie (expiry=0)
	c0 := cookies[0]
	if c0.Name != "token" {
		t.Errorf("expected name token, got %s", c0.Name)
	}
	if c0.Expires != nil {
		t.Error("expected nil Expires for session cookie")
	}
}

func TestParseNetscape_HttpOnlyPrefix(t *testing.T) {
	data := `#HttpOnly_.example.com	TRUE	/	FALSE	1744329600	secret	private
`

	cookies, err := ParseNetscape(strings.NewReader(data), time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC))
	if err != nil {
		t.Fatalf("ParseNetscape failed: %v", err)
	}

	if len(cookies) != 1 {
		t.Fatalf("expected 1 cookie, got %d", len(cookies))
	}

	c := cookies[0]
	if !c.HTTPOnly {
		t.Error("expected httpOnly=true from #HttpOnly_ prefix")
	}
	if c.Domain != "example.com" {
		t.Errorf("expected domain example.com (stripped), got %s", c.Domain)
	}
}

func TestParseNetscape_ExpiredCookie(t *testing.T) {
	// Expired cookie should be skipped
	data := `example.com	TRUE	/	FALSE	1000000000	old	cookie
`

	now := time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC)
	cookies, err := ParseNetscape(strings.NewReader(data), now)
	if err != nil {
		t.Fatalf("ParseNetscape failed: %v", err)
	}

	if len(cookies) != 0 {
		t.Errorf("expected 0 cookies (expired), got %d", len(cookies))
	}
}

func TestParseNetscape_EmptyDomain(t *testing.T) {
	data := `	TRUE	/	FALSE	1744329600	noop	val
`

	cookies, err := ParseNetscape(strings.NewReader(data), time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC))
	if err != nil {
		t.Fatalf("ParseNetscape failed: %v", err)
	}

	if len(cookies) != 0 {
		t.Errorf("expected 0 cookies (empty domain), got %d", len(cookies))
	}
}

func TestParseNetscape_MalformedLine(t *testing.T) {
	data := `# just a comment
example.com	TRUE	/	FALSE	2000000000	name	value
trash line that will be skipped
`

	cookies, err := ParseNetscape(strings.NewReader(data), time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC))
	if err != nil {
		t.Fatalf("ParseNetscape failed: %v", err)
	}

	if len(cookies) != 1 {
		t.Fatalf("expected 1 cookie, got %d", len(cookies))
	}
}

func TestParseNetscape_EmptyFile(t *testing.T) {
	cookies, err := ParseNetscape(strings.NewReader(""), time.Now())
	if err != nil {
		t.Fatalf("ParseNetscape failed: %v", err)
	}
	if len(cookies) != 0 {
		t.Errorf("expected 0 cookies, got %d", len(cookies))
	}
}

func TestParseNetscape_CommentOnly(t *testing.T) {
	data := `# Netscape HTTP Cookie File
# just comments
# no actual cookies
`
	cookies, err := ParseNetscape(strings.NewReader(data), time.Now())
	if err != nil {
		t.Fatalf("ParseNetscape failed: %v", err)
	}
	if len(cookies) != 0 {
		t.Errorf("expected 0 cookies, got %d", len(cookies))
	}
}

func TestParseNetscape_SameSiteDefault(t *testing.T) {
	data := `example.com	TRUE	/	FALSE	2000000000	sess	val
`

	cookies, err := ParseNetscape(strings.NewReader(data), time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC))
	if err != nil {
		t.Fatalf("ParseNetscape failed: %v", err)
	}

	if len(cookies) != 1 {
		t.Fatalf("expected 1 cookie, got %d", len(cookies))
	}

	if cookies[0].SameSite != network.CookieSameSite("Lax") {
		t.Errorf("expected SameSite Lax, got %s", cookies[0].SameSite)
	}
}
