// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package web

import (
	"bytes"
	"fmt"
	"html/template"
	"io/fs"
	"net/http"
	"net/url"
	"path"
	"regexp"
	"strings"
	"unicode/utf8"

	"github.com/yuin/goldmark"
	"github.com/yuin/goldmark/ast"
	"github.com/yuin/goldmark/extension"
	"github.com/yuin/goldmark/parser"
	"github.com/yuin/goldmark/renderer/html"
	"github.com/yuin/goldmark/text"
	"github.com/yuin/goldmark/util"
	"golang.org/x/website/internal/tmplfunc"
)

// RenderContent returns the HTML rendering for the page using the named base template
// (the standard base template is "site.tmpl").
func (site *Site) RenderContent(p Page, tmpl string) (template.HTML, error) {
	html, err := site.renderHTML(p, tmpl, &http.Request{URL: &url.URL{Path: "/missingurl"}})
	if err != nil {
		return "", err
	}
	return template.HTML(html), nil
}

// renderHTML renders and returns the Content and framed HTML for the page.
func (site *Site) renderHTML(p Page, tmpl string, r *http.Request) ([]byte, error) {
	// Clone p, because we are going to set its Content key-value pair.
	p2 := make(Page)
	for k, v := range p {
		p2[k] = v
	}
	p = p2

	url, ok := p["URL"].(string)
	if !ok {
		// Set URL - caller did not.
		p["URL"] = r.URL.Path
	}
	file, _ := p["File"].(string)
	data, _ := p["FileData"].(string)

	// Load base template.
	base, err := site.readFile(".", tmpl)
	if err != nil {
		return nil, err
	}

	dir := strings.Trim(path.Dir(url), "/")
	if dir == "" {
		dir = "."
	}
	sd := &siteDir{site, dir}

	t := template.New("site.tmpl").Funcs(template.FuncMap{
		"add":          func(a, b int) int { return a + b },
		"sub":          func(a, b int) int { return a - b },
		"mul":          func(a, b int) int { return a * b },
		"div":          func(a, b int) int { return a / b },
		"code":         sd.code,
		"data":         sd.data,
		"page":         sd.page,
		"pages":        sd.pages,
		"play":         sd.play,
		"request":      func() *http.Request { return r },
		"path":         func() pkgPath { return pkgPath{} },
		"strings":      func() pkgStrings { return pkgStrings{} },
		"file":         sd.file,
		"first":        first,
		"markdown":     markdown,
		"raw":          raw,
		"yaml":         yamlFn,
		"presentStyle": presentStyle,
	})
	t.Funcs(site.funcs)

	if err := tmplfunc.Parse(t, string(base)); err != nil {
		return nil, err
	}

	// Load page-specific layout template.
	layout, _ := p["layout"].(string)
	if layout == "" {
		l, ok := site.findLayout(dir, "default")
		if ok {
			layout = l
		} else {
			layout = "none"
		}
	} else if path.IsAbs(layout) {
		layout = strings.TrimLeft(path.Clean(layout+".tmpl"), "/")
	} else if strings.Contains(layout, "/") {
		layout = path.Join(dir, layout+".tmpl")
	} else if layout != "none" {
		l, ok := site.findLayout(dir, layout)
		if !ok {
			return nil, fmt.Errorf("cannot find layout %q", layout)
		}
		layout = l
	}

	if layout != "none" {
		ldata, err := site.readFile(".", layout)
		if err != nil {
			return nil, err
		}
		if err := tmplfunc.Parse(t.New(layout), string(ldata)); err != nil {
			return nil, err
		}
	}

	var buf bytes.Buffer
	if _, ok := p["Content"]; !ok && data != "" {
		// The page must explicitly request templating with "template: true"
		// in its metadata. Markdown files are no longer treated as
		// templates by default.
		isTemplate, _ := p["template"].(bool)

		tdata := data
		if isTemplate {
			// Load content as a template.
			tf := t.New(file)
			if err := tmplfunc.Parse(tf, data); err != nil {
				return nil, err
			}
			if err := tf.Execute(&buf, p); err != nil {
				return nil, err
			}
			tdata = buf.String()
			buf.Reset()
		}

		if strings.HasSuffix(file, ".md") {
			html, err := markdownToHTML(tdata)
			if err != nil {
				return nil, err
			}
			p["Content"] = html
		} else {
			p["Content"] = template.HTML(tdata)
		}
	}

	if err := t.Execute(&buf, p); err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

// findLayout searches the start directory and parent directories for a template with the given base name.
func (site *Site) findLayout(dir, name string) (string, bool) {
	name += ".tmpl"
	for {
		abs := path.Join(dir, name)
		if _, err := fs.Stat(site.fs, abs); err == nil {
			return abs, true
		}
		if dir == "." {
			return "", false
		}
		dir = path.Dir(dir)
	}
}

// markdownToHTML converts Markdown to HTML.
// The Markdown source may contain raw HTML,
// and may contain Go template syntax if templating was not enabled.
func markdownToHTML(markdown string) (template.HTML, error) {
	// parser.WithHeadingAttribute allows custom ids on headings.
	// html.WithUnsafe allows use of raw HTML, which we need for tables.
	md := goldmark.New(
		goldmark.WithParserOptions(
			parser.WithHeadingAttribute(),
			parser.WithAutoHeadingID(),
			parser.WithASTTransformers(util.Prioritized(mdTransformFunc(mdLink), 1)),
		),
		goldmark.WithRendererOptions(html.WithUnsafe()),
		goldmark.WithExtensions(
			extension.NewTypographer(),
			extension.NewLinkify(
				extension.WithLinkifyAllowedProtocols([][]byte{[]byte("http"), []byte("https")}),
				extension.WithLinkifyEmailRegexp(regexp.MustCompile(`[^\x00-\x{10FFFF}]`)), // impossible
			),
			extension.DefinitionList,
			extension.NewTable(),
		),
	)
	var buf bytes.Buffer
	buf.WriteString("<div class='markdown'>\n")
	if err := md.Convert(replaceTabs([]byte(markdown)), &buf); err != nil {
		return "", err
	}
	buf.WriteString("</div>\n")
	return template.HTML(buf.Bytes()), nil
}

// mdTransformFunc is a func implementing parser.ASTTransformer.
type mdTransformFunc func(*ast.Document, text.Reader, parser.Context)

func (f mdTransformFunc) Transform(node *ast.Document, reader text.Reader, pc parser.Context) {
	f(node, reader, pc)
}

// mdLink walks doc, adding rel=noreferrer target=_blank to non-relative links.
func mdLink(doc *ast.Document, _ text.Reader, _ parser.Context) {
	mdLinkWalk(doc)
}

func mdLinkWalk(n ast.Node) {
	switch n := n.(type) {
	case *ast.Link:
		dest := string(n.Destination)
		if strings.HasPrefix(dest, "https://") || strings.HasPrefix(dest, "http://") {
			n.SetAttributeString("rel", []byte("noreferrer"))
			n.SetAttributeString("target", []byte("_blank"))
		}
		return
	case *ast.AutoLink:
		// All autolinks are non-relative.
		n.SetAttributeString("rel", []byte("noreferrer"))
		n.SetAttributeString("target", []byte("_blank"))
		return
	}

	for child := n.FirstChild(); child != nil; child = child.NextSibling() {
		mdLinkWalk(child)
	}
}

// replaceTabs replaces all tabs in text with spaces up to a 4-space tab stop.
//
// In Markdown, tabs used for indentation are required to be interpreted as
// 4-space tab stops. See https://spec.commonmark.org/0.30/#tabs.
// Go also renders nicely and more compactly on the screen with 4-space
// tab stops, while browsers often use 8-space.
// And Goldmark crashes in some inputs that mix spaces and tabs.
// Fix the crashes and make the Go code consistently compact across browsers,
// all while staying Markdown-compatible, by expanding to 4-space tab stops.
//
// This function does not handle multi-codepoint Unicode sequences correctly.
func replaceTabs(text []byte) []byte {
	var buf bytes.Buffer
	col := 0
	for len(text) > 0 {
		r, size := utf8.DecodeRune(text)
		text = text[size:]

		switch r {
		case '\n':
			buf.WriteByte('\n')
			col = 0

		case '\t':
			buf.WriteByte(' ')
			col++
			for col%4 != 0 {
				buf.WriteByte(' ')
				col++
			}

		default:
			buf.WriteRune(r)
			col++
		}
	}
	return buf.Bytes()
}
