// Copyright 2017 The Wuffs Authors.
//
// Licensed 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
//
//    https://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.

// +build ignore

package main

// gen.go generates data.go.
//
// Invoke it via "go generate".

import (
	"bytes"
	"fmt"
	"go/format"
	"io/ioutil"
	"os"
	"sort"
	"strings"
)

func main() {
	if err := main1(); err != nil {
		os.Stderr.WriteString(err.Error() + "\n")
		os.Exit(1)
	}
}

func main1() error {
	out.WriteString(header)
	reasons, err := loadReasons()
	if err != nil {
		return err
	}
	for _, reason := range reasons {
		nextTmp = 0
		names = map[string]bool{}
		if err := gen(reason); err != nil {
			return err
		}
	}
	out.WriteString(footer)

	formatted, err := format.Source(out.Bytes())
	if err != nil {
		return err
	}
	return ioutil.WriteFile("data.go", formatted, 0644)
}

func loadReasons() ([]string, error) {
	s, err := ioutil.ReadFile("axioms.md")
	if err != nil {
		return nil, err
	}
	dashes := []byte("\n\n---\n\n")
	if i := bytes.Index(s, dashes); i < 0 {
		return nil, fmt.Errorf("could not parse axioms.md")
	} else {
		s = s[i+len(dashes):]
	}
	ret := []string(nil)
	lquotes := []byte("`\"")
	rquotes := []byte("\"`")
	for {
		if i := bytes.Index(s, lquotes); i < 0 {
			break
		} else {
			s = s[i+len(lquotes):]
		}
		if i := bytes.Index(s, rquotes); i < 0 {
			break
		} else {
			ret = append(ret, string(s[:i]))
			s = s[i+len(rquotes):]
		}
	}
	return ret, nil
}

var (
	nextTmp int
	names   map[string]bool
	out     bytes.Buffer
)

func gen(reason string) error {
	fmt.Fprintf(&out, "\n{`%q`, func(q *checker, n *a.Assert) error {\n", reason)

	for i := 0; i < len(reason); i++ {
		b := reason[i]
		if (b < 0x20) || (0x7F <= b) {
			return fmt.Errorf("bad reason %q", reason)
		}
	}
	i := strings.IndexByte(reason, ':')
	if i < 0 {
		return fmt.Errorf("bad reason %q", reason)
	}
	claim := strings.TrimSpace(reason[:i])
	requirements := strings.Split(reason[i+1:], ";")

	if err := genClaim(claim); err != nil {
		return fmt.Errorf("bad claim %q: %v", claim, err)
	}
	for _, req := range requirements {
		req = strings.TrimSpace(req)
		if err := genReq(req); err != nil {
			return fmt.Errorf("bad req %q: %v", req, err)
		}
	}

	{
		namesAsList := []string(nil)
		for name := range names {
			namesAsList = append(namesAsList, name)
		}
		sort.Strings(namesAsList)
		for _, name := range namesAsList {
			fmt.Fprintf(&out, "_ = x%s\n", name)
		}
	}

	fmt.Fprintf(&out, "return nil }},\n")
	return nil
}

func genClaim(claim string) error {
	n, err := parse(claim)
	if err != nil {
		return err
	}
	if err := genParseBinaryOps(n, "n.Condition()"); err != nil {
		return err
	}
	return nil
}

func genParseBinaryOps(n *node, arg string) error {
	l := genName(n.lhs)
	r := genName(n.rhs)
	key := keys[n.op]
	if key == "" {
		return fmt.Errorf("bad op %q", n.op)
	}
	fmt.Fprintf(&out, "op, %s, %s := parseBinaryOp(%s)\n", l, r, arg)
	fmt.Fprintf(&out, "if op != t.ID%s { return errFailed }\n", key)
	if l[0] == 't' {
		if err := genParseBinaryOps(n.lhs, l); err != nil {
			return err
		}
	}
	if r[0] == 't' {
		if err := genParseBinaryOps(n.rhs, r); err != nil {
			return err
		}
	}
	return nil
}

func genName(n *node) string {
	if isConstant(n.op) {
		if n.op == "0" {
			return "zeroExpr"
		}
		return "$BAD_CONSTANT"
	}
	if isVariable(n.op) {
		names[n.op] = true
		return "x" + n.op
	}
	nextTmp++
	return fmt.Sprintf("t%d", nextTmp-1)
}

func genReq(req string) error {
	n, err := parse(req)
	if err != nil {
		return err
	}
	fmt.Fprintf(&out, "// %s\n", req)
	genArgValues(n)
	return genProveReasonRequirement(n, "")
}

func genArgValues(n *node) {
	switch {
	case isVariable(n.op):
		if names[n.op] {
			break
		}
		names[n.op] = true
		fmt.Fprintf(&out, "x%s := argValue(q.tm, n.Args(), %q)\n", n.op, n.op)
		fmt.Fprintf(&out, "if x%s == nil { return errFailed }\n", n.op)
	case isOp(n.op):
		genArgValues(n.lhs)
		genArgValues(n.rhs)
	}
}

func genProveReasonRequirement(n *node, name string) error {
	l := genName(n.lhs)
	r := genName(n.rhs)
	key := keys[n.op]
	if key == "" {
		return fmt.Errorf("bad op %q", n.op)
	}
	if l[0] == 't' {
		if err := genProveReasonRequirement(n.lhs, l); err != nil {
			return err
		}
	}
	if r[0] == 't' {
		if err := genProveReasonRequirement(n.rhs, r); err != nil {
			return err
		}
	}
	if name == "" {
		fmt.Fprintf(&out, "if err := proveReasonRequirement(q, t.ID%s, %s, %s); err != nil { return err }\n",
			key, l, r)
	} else {
		fmt.Fprintf(&out, "%s := a.NewExpr(0, t.ID%s, 0, %s.AsNode(), nil, %s.AsNode(), nil)\n",
			name, key, l, r)
	}
	return nil
}

func parse(s string) (*node, error) {
	n, s, err := parseExpr(s)
	if err != nil {
		return nil, err
	}
	if s != "" {
		return nil, fmt.Errorf("parse error")
	}
	return n, nil
}

func parseExpr(s string) (*node, string, error) {
	lhs, s, err := parseOperand(s)
	if err != nil {
		return nil, "", err
	}
	s = trim(s)
	if !isOp(s) {
		return nil, "", fmt.Errorf("parseExpr error")
	}
	i := 1
	for ; i < len(s) && isOpByte(s[i]); i++ {
	}
	op, s := s[:i], s[i:]
	s = trim(s)
	rhs, s, err := parseOperand(s)
	if err != nil {
		return nil, "", err
	}
	s = trim(s)
	return &node{
		op:  op,
		lhs: lhs,
		rhs: rhs,
	}, s, nil
}

func parseOperand(s string) (*node, string, error) {
	switch {
	case isConstant(s), isVariable(s):
		i := 1
		for ; i < len(s) && isAlphaNumByte(s[i]); i++ {
		}
		return &node{op: s[:i]}, s[i:], nil
	case isParen(s):
		n, s, err := parseExpr(s[1:])
		if err != nil {
			return nil, "", err
		}
		if len(s) > 0 && s[0] == ')' {
			return n, s[1:], nil
		}
	}
	return nil, "", fmt.Errorf("parseOperand error")
}

type node struct {
	op  string
	lhs *node
	rhs *node
}

func (n *node) String() string {
	if n == nil {
		return "$NIL_NODE"
	}
	switch {
	case isConstant(n.op), isVariable(n.op):
		return n.op
	case isOp(n.op):
		return fmt.Sprintf("(%s %v %v)", n.op, n.lhs, n.rhs)
	}
	return "$BAD_NODE"
}

func isConstant(s string) bool { return s != "" && '0' <= s[0] && s[0] <= '9' }
func isOp(s string) bool       { return s != "" && isOpByte(s[0]) }
func isParen(s string) bool    { return s != "" && '(' == s[0] }
func isVariable(s string) bool { return s != "" && 'a' <= s[0] && s[0] <= 'z' }

func isOpByte(b byte) bool       { return ('<' <= b && b <= '>') || '+' == b || '-' == b || '!' == b }
func isAlphaNumByte(b byte) bool { return ('0' <= b && b <= '9') || ('a' <= b && b <= 'z') }

func trim(s string) string {
	for ; len(s) > 0 && s[0] == ' '; s = s[1:] {
	}
	return s
}

var keys = map[string]string{
	"+":  "XBinaryPlus",
	"-":  "XBinaryMinus",
	"!=": "XBinaryNotEq",
	"<":  "XBinaryLessThan",
	"<=": "XBinaryLessEq",
	"==": "XBinaryEqEq",
	">=": "XBinaryGreaterEq",
	">":  "XBinaryGreaterThan",
}

const header = `// Code generated by running "go generate". DO NOT EDIT.

// Copyright 2017 The Wuffs Authors.
//
// Licensed 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
//
//    https://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 check

import (
	a "github.com/google/wuffs/lang/ast"
	t "github.com/google/wuffs/lang/token"
)

var reasons = [...]struct {
	s string
	r reason
}{
`

const footer = "}\n"
