package rss

import (
	"strings"
	"testing"
	"time"
)

const rss2 = `<?xml version="1.0"?>
<rss version="2.0">
 <channel>
  <title>Хабр</title>
  <item>
   <title>Новая уязвимость в ядре</title>
   <link>https://example.org/a</link>
   <description>&lt;p&gt;Патч уже &lt;b&gt;вышел&lt;/b&gt;.&lt;/p&gt;</description>
   <guid>tag:example.org,a</guid>
   <pubDate>Mon, 28 Jul 2026 10:00:00 +0000</pubDate>
  </item>
  <item>
   <title>Без даты</title>
   <link>https://example.org/b</link>
  </item>
 </channel>
</rss>`

const atom = `<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 <title>Example Atom</title>
 <entry>
  <title>Release 2.0</title>
  <link rel="alternate" href="https://example.com/rel"/>
  <link rel="edit" href="https://example.com/edit"/>
  <id>urn:uuid:1</id>
  <updated>2026-07-30T12:30:00Z</updated>
  <summary>Ships &amp; works</summary>
 </entry>
</feed>`

func TestParseRSS2(t *testing.T) {
	f, err := Parse(strings.NewReader(rss2))
	if err != nil {
		t.Fatal(err)
	}
	if f.Title != "Хабр" {
		t.Fatalf("title = %q", f.Title)
	}
	if len(f.Items) != 2 {
		t.Fatalf("items = %d, want 2", len(f.Items))
	}
	it := f.Items[0]
	if it.Title != "Новая уязвимость в ядре" {
		t.Errorf("title = %q", it.Title)
	}
	if it.Summary != "Патч уже вышел ." && it.Summary != "Патч уже вышел." {
		t.Errorf("summary = %q — tags must be stripped and entities decoded", it.Summary)
	}
	if it.ID != "tag:example.org,a" {
		t.Errorf("id = %q", it.ID)
	}
	if want := time.Date(2026, 7, 28, 10, 0, 0, 0, time.UTC); !it.Published.Equal(want) {
		t.Errorf("published = %v, want %v", it.Published, want)
	}
	if !f.Items[1].Published.IsZero() {
		t.Errorf("undated item got a date: %v", f.Items[1].Published)
	}
	if f.Items[1].ID != "https://example.org/b" {
		t.Errorf("id falls back to the link, got %q", f.Items[1].ID)
	}
}

func TestParseAtom(t *testing.T) {
	f, err := Parse(strings.NewReader(atom))
	if err != nil {
		t.Fatal(err)
	}
	if f.Title != "Example Atom" || len(f.Items) != 1 {
		t.Fatalf("feed = %+v", f)
	}
	it := f.Items[0]
	if it.Link != "https://example.com/rel" {
		t.Errorf("link = %q, want the alternate link", it.Link)
	}
	if it.Summary != "Ships & works" {
		t.Errorf("summary = %q", it.Summary)
	}
	if want := time.Date(2026, 7, 30, 12, 30, 0, 0, time.UTC); !it.Published.Equal(want) {
		t.Errorf("published = %v, want %v", it.Published, want)
	}
}

func TestParseGarbage(t *testing.T) {
	if _, err := Parse(strings.NewReader("<html><body>not a feed")); err == nil {
		t.Fatal("want an error on a non-feed document")
	}
	// A feed with an item that has neither title nor link contributes nothing
	// rather than an empty note.
	f, err := Parse(strings.NewReader(`<rss><channel><item><description>x</description></item></channel></rss>`))
	if err != nil {
		t.Fatal(err)
	}
	if len(f.Items) != 0 {
		t.Fatalf("items = %d, want 0", len(f.Items))
	}
}

func TestPlainTextDropsScript(t *testing.T) {
	got := PlainText(`<p>hi</p><script>alert("x")</script><style>b{}</style> there`)
	if got != "hi there" {
		t.Fatalf("got %q", got)
	}
}
