// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"go/format"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"text/template"
)

const Ext = ".tmpl"

type pathSpec struct {
	in, out string
}

func (p *pathSpec) String() string { return p.in + " → " + p.out }
func (p *pathSpec) IsGoFile() bool { return filepath.Ext(p.out) == ".go" }

func parsePath(path string) (string, string) {
	p := strings.IndexByte(path, '=')
	if p == -1 {
		if filepath.Ext(path) != Ext {
			errExit("template file '%s' must have .tmpl extension", path)
		}
		return path, path[:len(path)-len(Ext)]
	}

	return path[:p], path[p+1:]
}

type data struct {
	In interface{}
	D  listValue
}

func errExit(format string, a ...interface{}) {
	fmt.Fprintf(os.Stderr, format, a...)
	fmt.Fprintln(os.Stderr)
	os.Exit(1)
}

type listValue map[string]string

func (l listValue) String() string {
	res := make([]string, 0, len(l))
	for k, v := range l {
		res = append(res, fmt.Sprintf("%s=%s", k, v))
	}
	return strings.Join(res, ", ")
}

func (l listValue) Set(v string) error {
	nv := strings.Split(v, "=")
	if len(nv) != 2 {
		return fmt.Errorf("expected NAME=VALUE, got %s", v)
	}
	l[nv[0]] = nv[1]
	return nil
}

func main() {
	var (
		dataArg = flag.String("data", "", "input JSON data")
		gi      = flag.Bool("i", false, "run goimports")
		in      = &data{D: make(listValue)}
	)

	flag.Var(&in.D, "d", "-d NAME=VALUE")

	flag.Parse()
	if *dataArg == "" {
		errExit("data option is required")
	}

	if *gi {
		if _, err := exec.LookPath("goimports"); err != nil {
			errExit("failed to find goimports: %s", err.Error())
		}
		formatter = formatSource
	} else {
		formatter = format.Source
	}

	paths := flag.Args()
	if len(paths) == 0 {
		errExit("no tmpl files specified")
	}

	specs := make([]pathSpec, len(paths))
	for i, p := range paths {
		in, out := parsePath(p)
		specs[i] = pathSpec{in: in, out: out}
	}

	in.In = readData(*dataArg)
	process(in, specs)
}

func mustReadAll(path string) []byte {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		errExit(err.Error())
	}

	return data
}

func readData(path string) interface{} {
	data := mustReadAll(path)
	var v interface{}
	if err := json.Unmarshal(StripComments(data), &v); err != nil {
		errExit("invalid JSON data: %s", err.Error())
	}
	return v
}

func fileMode(path string) os.FileMode {
	stat, err := os.Stat(path)
	if err != nil {
		errExit(err.Error())
	}
	return stat.Mode()
}

var funcs = template.FuncMap{
	"lower": strings.ToLower,
	"upper": strings.ToUpper,
}

func process(data interface{}, specs []pathSpec) {
	for _, spec := range specs {
		var (
			t   *template.Template
			err error
		)
		t, err = template.New("gen").Funcs(funcs).Parse(string(mustReadAll(spec.in)))
		if err != nil {
			errExit("error processing template '%s': %s", spec.in, err.Error())
		}

		var buf bytes.Buffer
		if spec.IsGoFile() {
			// preamble
			fmt.Fprintf(&buf, "// Code generated by %s. DO NOT EDIT.\n", spec.in)
			fmt.Fprintln(&buf)
		}
		err = t.Execute(&buf, data)
		if err != nil {
			errExit("error executing template '%s': %s", spec.in, err.Error())
		}

		generated := buf.Bytes()
		if spec.IsGoFile() {
			generated, err = formatter(generated)
			if err != nil {
				errExit("error formatting '%s': %s", spec.in, err.Error())
			}
		}

		ioutil.WriteFile(spec.out, generated, fileMode(spec.in))
	}
}

var (
	formatter func([]byte) ([]byte, error)
)

func formatSource(in []byte) ([]byte, error) {
	r := bytes.NewReader(in)
	cmd := exec.Command("goimports")
	cmd.Stdin = r
	out, err := cmd.Output()
	if err != nil {
		if ee, ok := err.(*exec.ExitError); ok {
			return nil, fmt.Errorf("error running goimports: %s", string(ee.Stderr))
		}
		return nil, fmt.Errorf("error running goimports: %s", string(out))
	}

	return out, nil
}

func StripComments(raw []byte) []byte {
	var (
		quoted, esc bool
		comment     bool
	)

	buf := bytes.Buffer{}

	for i := 0; i < len(raw); i++ {
		b := raw[i]

		if comment {
			switch b {
			case '/':
				comment = false
				j := bytes.IndexByte(raw[i+1:], '\n')
				if j == -1 {
					i = len(raw)
				} else {
					i += j // keep new line
				}
			case '*':
				j := bytes.Index(raw[i+1:], []byte("*/"))
				if j == -1 {
					i = len(raw)
				} else {
					i += j + 2
					comment = false
				}
			}
			continue
		}

		if esc {
			esc = false
			continue
		}

		if b == '\\' && quoted {
			esc = true
			continue
		}

		if b == '"' || b == '\'' {
			quoted = !quoted
		}

		if b == '/' && !quoted {
			comment = true
			continue
		}

		buf.WriteByte(b)
	}

	if quoted || esc || comment {
		// unexpected state, so return raw bytes
		return raw
	}

	return buf.Bytes()
}
