// +build ignore

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"log"
	"os/exec"
	"path/filepath"
)

// ignoreFile uses "git check-ignore" to determine if we should ignore a file.
func ignoreFile(p string) (ok bool, err error) {
	err = exec.Command("git", "check-ignore", p).Run()
	if err == nil {
		return true, nil
	}
	exitErr, ok := err.(*exec.ExitError)
	if ok {
		if sys := exitErr.Sys(); sys != nil {
			e, ok := sys.(interface {
				// Is the returned value something that returns an exit status?
				ExitStatus() int
			})
			if ok && e.ExitStatus() == 1 {
				return false, nil
			}
		}
	}
	return false, err
}

// Maps aren't deterministic, use a struct instead.

type fileData struct {
	name string
	data string
}

func main() {
	// ReadDir guarentees result in sorted order.
	dir, err := ioutil.ReadDir("web/templates")
	if err != nil {
		log.Fatal(err)
	}
	files := []fileData{}
	for _, file := range dir {
		p := filepath.Join("web/templates", file.Name())
		ignore, err := ignoreFile(p)
		if err != nil {
			log.Fatal(err)
		}
		if ignore {
			continue
		}

		data, err := ioutil.ReadFile(p)
		if err != nil {
			log.Fatal(err)
		}
		if bytes.Contains(data, []byte{'`'}) {
			log.Fatalf("file %s contains escape character '`' and cannot be compiled into go source", p)
		}
		files = append(files, fileData{file.Name(), string(data)})
	}

	f := new(bytes.Buffer)

	fmt.Fprintln(f, "// This file was generated by the makefile. Do not edit.")
	fmt.Fprintln(f)
	fmt.Fprintln(f, "package server")
	fmt.Fprintln(f)
	fmt.Fprintln(f, "// defaultTemplates is a key for file name to file data of the files in web/templates.")
	fmt.Fprintln(f, "var defaultTemplates = map[string]string{")
	for _, file := range files {
		fmt.Fprintf(f, "\t%q: `%s`,\n", file.name, file.data)
	}
	fmt.Fprintln(f, "}")

	if err := ioutil.WriteFile("server/templates_default.go", f.Bytes(), 0644); err != nil {
		log.Fatal(err)
	}
}
