package caddyhugo

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"html/template"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"strings"
	"sync"

	"git.stephensearles.com/stephen/acedoc"
	"git.stephensearles.com/stephen/caddy-hugo2/frontend"
)

func (t *tmplData) Content() ([]Content, error) {
	return GetContent(t.Site.Root, t.HugoSites)
}

func (t *tmplData) ContentTypes() ([]string, error) {
	nameMap := map[string]struct{}{"default": struct{}{}}

	names, err := t.contentTypes(path.Join(t.Site.Root, "archetypes"))
	if err != nil {
		return nil, err
	}
	for _, name := range names {
		nameMap[name] = struct{}{}
	}

	names, err = t.contentTypes(path.Join(t.Site.Root, "themes", "hugo-theme-minos", "archetypes"))
	if err != nil {
		return nil, err
	}
	for _, name := range names {
		nameMap[name] = struct{}{}
	}

	var out []string
	for name := range nameMap {
		out = append(out, name[:len(name)-len(filepath.Ext(name))])
	}

	return out, nil
}

func (t *tmplData) contentTypes(dir string) ([]string, error) {
	layoutDir, err := os.Open(path.Join(t.Site.Root, "archetypes"))
	if err != nil {
		fmt.Println("opening layout dir", err)
		return nil, err
	}
	defer layoutDir.Close()

	names, err := layoutDir.Readdirnames(0)
	if err != nil {
		fmt.Println("reading dir", err)
		return nil, err
	}

	return names, nil
}

type tmplData struct {
	Site SiteConfig
	R    *http.Request
	*CaddyHugo
	Doc    *acedoc.Document
	docref *editSession
}

func (t *tmplData) LoadContent() (string, error) {
	return t.Doc.Contents(), nil
}

func baseNoExt(name string) string {
	base := path.Base(name)
	return base[:len(base)-len(path.Ext(base))]
}

func (t *tmplData) IframeSource() string {
	name := baseNoExt(t.docref.docname)
	ctype := baseNoExt(path.Dir(t.docref.docname))
	if ctype == "content" {
		return fmt.Sprintf("/hugo/draft/%s/%s/", base64.RawURLEncoding.EncodeToString([]byte(t.docref.docname)), strings.Replace(name, " ", "-", -1))
	}
	return fmt.Sprintf("/hugo/draft/%s/%s/%s/", base64.RawURLEncoding.EncodeToString([]byte(t.docref.docname)), ctype, strings.Replace(name, " ", "-", -1))
}

var EditPage = frontend.EditPage()

var AdminPage = frontend.AdminPage()

var AuthorPage = frontend.AuthorPage()

var uploadTmpl *template.Template
var uploadTmplOnce sync.Once

func UploadPage(elemName string) string {
	uploadTmplOnce.Do(func() {
		p := frontend.UploadPage()
		t, err := template.New("").Parse(p)
		if err != nil {
			panic(err)
		}
		uploadTmpl = t
	})

	var buf bytes.Buffer
	err := uploadTmpl.Execute(&buf, struct{ ElemName string }{elemName})
	if err != nil {
		panic(err)
	}
	return buf.String()
}
