package controllers

import (
	"fmt"
	"mime"
	"net/http"
	"path/filepath"
	"strings"
	"time"

	"git.kirsle.net/apps/gophertype/pkg/common"
	"git.kirsle.net/apps/gophertype/pkg/models"
	"git.kirsle.net/apps/gophertype/pkg/responses"
	"git.kirsle.net/apps/gophertype/pkg/settings"
	"github.com/gorilla/feeds"
)

// RSSFeed returns the RSS (or Atom) feed for the blog.
func RSSFeed(w http.ResponseWriter, r *http.Request) {
	// Get the first (admin) user for the feed.
	admin, err := models.Users.FirstAdmin()
	if err != nil {
		responses.Error(w, r, http.StatusBadRequest, "Blog isn't ready yet.")
		return
	}

	feed := &feeds.Feed{
		Title:       settings.Current.Title,
		Link:        &feeds.Link{Href: settings.Current.BaseURL},
		Description: settings.Current.Description,
		Author: &feeds.Author{
			Name:  admin.Name,
			Email: admin.Email,
		},
		Created: time.Now(),
		Items:   []*feeds.Item{},
	}

	pp, err := models.Posts.GetIndexPosts(models.Public, 1, settings.Current.PostsPerPage)
	if err != nil {
		responses.Error(w, r, http.StatusInternalServerError, err.Error())
		return
	}

	for _, post := range pp.Posts {
		// If blog is NSFW, allow feed readers to skip the age gate.
		var urlSuffix string
		if settings.Current.NSFW {
			urlSuffix = "?over18=1"
		}

		item := &feeds.Item{
			Id:    fmt.Sprintf("%d", post.ID),
			Title: post.Title,
			Link:  &feeds.Link{Href: settings.Current.BaseURL + "/" + post.Fragment + urlSuffix},
			// Description is the HTML with relative links made absolute.
			Description: common.ReplaceRelativeLinksToAbsolute(settings.Current.BaseURL, string(post.HTML())),
			Created:     post.CreatedAt,
		}

		// Attach the thumbnail?
		if post.Thumbnail != "" {
			item.Enclosure = &feeds.Enclosure{
				Url:  common.ToAbsoluteURL(post.Thumbnail, settings.Current.BaseURL),
				Type: mime.TypeByExtension(filepath.Ext(post.Thumbnail)),
			}
		}

		feed.Items = append(feed.Items, item)
	}

	// What format to encode it in?
	if strings.Contains(r.URL.Path, ".atom") {
		atom, _ := feed.ToAtom()
		w.Header().Set("Content-Type", "application/atom+xml; encoding=utf-8")
		w.Write([]byte(atom))
	} else if strings.Contains(r.URL.Path, ".json") {
		jsonData, _ := feed.ToJSON()
		w.Header().Set("Content-Type", "application/json; encoding=utf-8")
		w.Write([]byte(jsonData))
	} else {
		rss, _ := feed.ToRss()
		w.Header().Set("Content-Type", "application/rss+xml; encoding=utf-8")
		w.Write([]byte(rss))
	}
}
