package caddyhugo

import (
	"html/template"
	"net/http"
	"path/filepath"
	"strings"
	"sync"

	"git.stephensearles.com/stephen/acedoc"
	"git.stephensearles.com/stephen/caddy-hugo2/comments"
	"git.stephensearles.com/stephen/caddy-hugo2/media"

	"github.com/gohugoio/hugo/deps"
	"github.com/gohugoio/hugo/hugolib"
	"github.com/mholt/caddy"
	"github.com/mholt/caddy/caddyhttp/httpserver"
	"github.com/spf13/afero"
)

func init() {
	caddy.RegisterPlugin("hugo", caddy.Plugin{
		ServerType: "http",
		Action:     SetupCaddy,
	})
}

// CaddyHugo implements the plugin
type CaddyHugo struct {
	ServerType string
	Site       *httpserver.SiteConfig
	HugoSites  *hugolib.HugoSites
	HugoCfg    *deps.DepsCfg

	Dir string

	Media    *media.MediaSource
	Comments *comments.Service

	docs map[string]*editSession
	mtx  sync.Mutex

	authorTmpl, adminTmpl, editTmpl *template.Template

	ltime              uint64
	confirmingToClient map[uint64]struct{}
}

// Build rebuilds the cached state of the site. TODO: determine if this republishes
func (ch *CaddyHugo) Build() error {
	return buildSite(ch.HugoSites)
}

// BasePath returns the directory that the CaddyHugo internal/author pages are under
func (ch *CaddyHugo) BasePath() string {
	return "/hugo"
}

func docname(orig string) string {
	orig = strings.Replace(orig, " ", "-", -1)
	return strings.ToLower(orig)
}

func (ch *CaddyHugo) docFilename(orig string) string {
	return filepath.Join(ch.Dir, docname(orig))
}

// TmplData collects data for template execution
func (ch *CaddyHugo) TmplData(r *http.Request, docref *editSession) interface{} {
	var doc *acedoc.Document
	if docref != nil {
		doc = docref.doc
	}
	if ch.HugoSites != nil && ch.HugoSites.Fs != nil {
		ch.HugoSites.Cfg.Set("buildDrafts", true)
		ch.HugoSites.Fs.Destination = afero.NewMemMapFs()
		ch.Build()
	}
	return &tmplData{ch.Site, r, ch, doc, docref}
}
