package main

import (
	"bytes"
	"html/template"
	"net/url"
	"strings"

	"code.hackerspace.pl/hscloud/devtools/hackdoc/config"

	"github.com/gabriel-vasile/mimetype"
	"github.com/golang/glog"
	"github.com/russross/blackfriday/v2"
)

// renderMarkdown renders markdown to HTML, replacing all relative (intra-hackdoc) links with version that have ref set.
func renderMarkdown(input []byte, ref string) []byte {
	r := blackfriday.NewHTMLRenderer(blackfriday.HTMLRendererParameters{
		Flags: blackfriday.CommonHTMLFlags | blackfriday.TOC,
	})

	// master is the default branch - do not make special links for that, as
	// that makes them kinda ugly.
	if ref == flagGitwebDefaultBranch {
		ref = ""
	}

	parser := blackfriday.New(blackfriday.WithRenderer(r), blackfriday.WithExtensions(blackfriday.CommonExtensions))
	ast := parser.Parse(input)

	// Render table of contents (raw HTML) into bytes.
	var tocB bytes.Buffer
	tocB.Write([]byte(`<div class="toc">`))
	r.RenderHeader(&tocB, ast)
	tocB.Write([]byte(`</div>`))
	toc := tocB.Bytes()

	var buf bytes.Buffer
	buf.Write([]byte(`<div class="content">`))
	// Render Markdown with some custom behaviour.
	ast.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
		// Fix intra-hackdoc links to contain ?ref=
		if ref != "" && entering && node.Type == blackfriday.Link || node.Type == blackfriday.Image {
			dest := string(node.Destination)
			u, err := url.Parse(dest)
			if err == nil && !u.IsAbs() {
				q := u.Query()
				q["ref"] = []string{ref}
				u.RawQuery = q.Encode()
				node.Destination = []byte(u.String())
				glog.V(10).Infof("link fix %q -> %q", dest, u.String())
			}
		}
		// Replace [TOC] anchor with a rendered TOC.
		if entering && node.Type == blackfriday.Text && string(node.Literal) == "[TOC]" {
			buf.Write(toc)
			return blackfriday.GoToNext
		}
		return r.RenderNode(&buf, node, entering)
	})
	buf.Write([]byte(`</div>`))
	r.RenderFooter(&buf, ast)
	return buf.Bytes()
}

type pathPart struct {
	Label string
	Path  string
}

func (r *request) renderable(dirpath string) bool {
	cfg, err := config.ForPath(r.ctx, r.source, dirpath)
	if err != nil {
		glog.Errorf("could not get config for path %q: %v", dirpath, err)
		return false
	}

	for _, f := range cfg.DefaultIndex {
		fpath := dirpath + "/" + f
		file, err := r.source.IsFile(r.ctx, fpath)
		if err != nil {
			glog.Errorf("IsFile(%q): %v", fpath, err)
			return false
		}

		if file {
			return true
		}
	}

	return false
}

func (r *request) handleFile(path string, cfg *config.Config) {
	data, err := r.source.ReadFile(r.ctx, path)
	if err != nil {
		glog.Errorf("ReadFile(%q): %w", err)
		r.handle500()
		return
	}

	// TODO(q3k): do MIME detection instead.
	if strings.HasSuffix(path, ".md") {
		rendered := renderMarkdown([]byte(data), r.ref)

		r.logRequest("serving markdown at %s, cfg %+v", path, cfg)

		// TODO(q3k): allow markdown files to override which template to load
		tmpl, ok := cfg.Templates["default"]
		if !ok {
			glog.Errorf("No default template found for %s", path)
			// TODO(q3k): implement fallback template
			r.w.Write(rendered)
			return
		}

		pathInDepot := strings.TrimPrefix(path, "//")
		pathParts := []pathPart{
			{Label: "//", Path: "/"},
		}
		parts := strings.Split(pathInDepot, "/")
		fullPath := ""
		for i, p := range parts {
			label := p
			if i != len(parts)-1 {
				label = label + "/"
			}
			fullPath += "/" + p
			target := fullPath
			if i != len(parts)-1 && !r.renderable("/"+fullPath) {
				target = ""
			}
			pathParts = append(pathParts, pathPart{Label: label, Path: target})
		}

		vars := map[string]interface{}{
			"Rendered":    template.HTML(rendered),
			"Title":       path,
			"Path":        path,
			"PathInDepot": pathInDepot,
			"PathParts":   pathParts,
			"HackdocURL":  flagHackdocURL,
			"WebLinks":    r.source.WebLinks(pathInDepot),
		}
		err = tmpl.Execute(r.w, vars)
		if err != nil {
			glog.Errorf("Could not execute template for %s: %v", err)
		}

		return
	}

	// Just serve the file.
	var mime string
	if strings.HasSuffix(path, ".js") {
		// Force .js to always be the correct MIME type.
		mime = "text/javascript"
	} else {
		// Otherwise, use magic to detect type.
		mime = mimetype.Detect(data).String()
	}
	r.w.Header().Set("Content-Type", mime)
	r.w.Write(data)
}
