package main

import (
	"bytes"
	"fmt"
	"html/template"
	"io/ioutil"
	"os"
	"regexp"
	"strings"

	"github.com/microcosm-cc/bluemonday"
	"github.com/russross/blackfriday"
	yaml "gopkg.in/yaml.v2"
)

const delim = "---"

type post struct {
	Title       string
	Published   bool
	Description string
	Tags        []string
	CoverImage  string
	Series      string
	PostBody    template.HTML
}

var templ = `<!DOCTYPE html>
<html lang="en">
  <head>
    <title>{{.Title}}</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="HandheldFriendly" content="True">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="referrer" content="no-referrer-when-downgrade" />
    <meta name="description" content="{{.Description}}" />
  </head>
	<body>
		<div class="post">
			<h1>{{.Title}}</h1>
			{{.PostBody}}
		</div>
	</body>
	</html>
	`

func loadFile(s string) (b []byte, err error) {
	f, err := ioutil.ReadFile(s)
	if err != nil {
		return nil, err
	}
	return f, nil
}

func isNil(i interface{}) bool {
	if i != nil {
		return false
	}
	return true
}

func main() {
	f, err := loadFile("test.md")
	if err != nil {
		panic(err)
	}

	// Not the best test
	b := bytes.Split(f, []byte(delim))
	if len(b) < 3 || len(b[0]) != 0 {
		panic(fmt.Errorf("Front matter is damaged"))
	}

	m := make(map[string]interface{})
	err = yaml.Unmarshal([]byte(b[1]), &m)
	if err != nil {
		msg := fmt.Sprintf("error: %v\ninput:\n%s", err, b[1])
		panic(msg)
	}

	p := &post{}

	if isNil(m["title"]) {
		panic(err)
	} else {
		p.Title = m["title"].(string)
	}
	p.Published = m["published"].(bool)
	p.Description = m["description"].(string)

	// TODO: Strip space after comma prior to parse?
	tmp := m["tags"].(string)
	p.Tags = strings.Split(tmp, ", ")

	p.CoverImage = m["cover_image"].(string)
	p.Series = m["series"].(string)

	pBody := f[len(b[1])+(len(delim)*2):]

	out := blackfriday.Run(pBody)

	bm := bluemonday.UGCPolicy()
	bm.AllowAttrs("class").Matching(regexp.MustCompile("^language-[a-zA-Z0-9]+$")).OnElements("code")
	p.PostBody = template.HTML(bm.SanitizeBytes(out))
	// p.PostBody = template.HTML(bluemonday.UGCPolicy().SanitizeBytes(out))

	t := template.Must(template.New("msg").Parse(templ))

	err = t.Execute(os.Stdout, p)
	if err != nil {
		panic(err)
	}
}