// Copyright 2020 CUE 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
//
//     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 debug prints a given ADT node.
//
// Note that the result is not valid CUE, but instead prints the internals
// of an ADT node in human-readable form. It uses a simple indentation algorithm
// for improved readability and diffing.
//
package debug

import (
	"fmt"
	"io"
	"strconv"
	"strings"

	"cuelang.org/go/cue/errors"
	"cuelang.org/go/internal"
	"cuelang.org/go/internal/core/adt"
	"golang.org/x/xerrors"
)

const (
	openTuple  = "\u3008"
	closeTuple = "\u3009"
)

type Config struct {
	Cwd     string
	Compact bool
	Raw     bool
}

func WriteNode(w io.Writer, i adt.StringIndexer, n adt.Node, config *Config) {
	if config == nil {
		config = &Config{}
	}
	p := printer{Writer: w, index: i, cfg: config}
	if config.Compact {
		p := compactPrinter{p}
		p.node(n)
	} else {
		p.node(n)
	}
}

func NodeString(i adt.StringIndexer, n adt.Node, config *Config) string {
	b := &strings.Builder{}
	WriteNode(b, i, n, config)
	return b.String()
}

type printer struct {
	io.Writer
	index  adt.StringIndexer
	indent string
	cfg    *Config

	// modes:
	// - show vertex
	// - show original conjuncts
	// - show unevaluated
	// - auto
}

func (w *printer) string(s string) {
	s = strings.Replace(s, "\n", "\n"+w.indent, -1)
	_, _ = io.WriteString(w, s)
}

func (w *printer) label(f adt.Feature) {
	w.string(w.labelString(f))
}

// TODO: fold into label once :: is no longer supported.
func (w *printer) labelString(f adt.Feature) string {
	return f.SelectorString(w.index)
}

func (w *printer) shortError(errs errors.Error) {
	for {
		msg, args := errs.Msg()
		fmt.Fprintf(w, msg, args...)

		err := xerrors.Unwrap(errs)
		if err == nil {
			break
		}

		if errs, _ = err.(errors.Error); errs != nil {
			w.string(err.Error())
			break
		}
	}
}

func (w *printer) interpolation(x *adt.Interpolation) {
	quote := `"`
	if x.K == adt.BytesKind {
		quote = `'`
	}
	w.string(quote)
	for i := 0; i < len(x.Parts); i += 2 {
		switch x.K {
		case adt.StringKind:
			if s, ok := x.Parts[i].(*adt.String); ok {
				w.string(s.Str)
			} else {
				w.string("<bad string>")
			}
		case adt.BytesKind:
			if s, ok := x.Parts[i].(*adt.Bytes); ok {
				_, _ = w.Write(s.B)
			} else {
				w.string("<bad bytes>")
			}
		}
		if i+1 < len(x.Parts) {
			w.string(`\(`)
			w.node(x.Parts[i+1])
			w.string(`)`)
		}
	}
	w.string(quote)
}

func (w *printer) node(n adt.Node) {
	switch x := n.(type) {
	case *adt.Vertex:
		var kind adt.Kind
		if x.Value != nil {
			kind = x.Value.Kind()
		}

		kindStr := kind.String()

		// TODO: replace with showing full closedness data.
		if x.IsClosed(nil) {
			if kind == adt.ListKind || kind == adt.StructKind {
				kindStr = "#" + kindStr
			}
		}

		fmt.Fprintf(w, "(%s){", kindStr)

		saved := w.indent
		w.indent += "  "
		defer func() { w.indent = saved }()

		switch v := x.Value.(type) {
		case nil:
		case *adt.Bottom:
			// TODO: reuse bottom.
			saved := w.indent
			w.indent += "// "
			w.string("\n")
			fmt.Fprintf(w, "[%v]", v.Code)
			if !v.ChildError {
				msg := errors.Details(v.Err, &errors.Config{
					Cwd:     w.cfg.Cwd,
					ToSlash: true,
				})
				msg = strings.TrimSpace(msg)
				if msg != "" {
					w.string(" ")
					w.string(msg)
				}
			}
			w.indent = saved

		case *adt.StructMarker, *adt.ListMarker:
			// if len(x.Arcs) == 0 {
			// 	// w.string("}")
			// 	// return
			// }

		default:
			if len(x.Arcs) == 0 {
				w.string(" ")
				w.node(x.Value)
				w.string(" }")
				return
			}
			w.string("\n")
			w.node(x.Value)
		}

		for _, a := range x.Arcs {
			w.string("\n")
			w.label(a.Label)
			w.string(": ")
			w.node(a)
		}

		if x.Value == nil {
			w.indent += "// "
			w.string("// ")
			for i, c := range x.Conjuncts {
				if i > 0 {
					w.string(" & ")
				}
				w.node(c.Expr()) // TODO: also include env?
			}
		}

		w.indent = saved
		w.string("\n")
		w.string("}")

	case *adt.StructMarker:
		w.string("struct")

	case *adt.ListMarker:
		w.string("list")

	case *adt.StructLit:
		if len(x.Decls) == 0 {
			w.string("{}")
			break
		}
		w.string("{")
		w.indent += "  "
		for _, d := range x.Decls {
			w.string("\n")
			w.node(d)
		}
		w.indent = w.indent[:len(w.indent)-2]
		w.string("\n}")

	case *adt.ListLit:
		if len(x.Elems) == 0 {
			w.string("[]")
			break
		}
		w.string("[")
		w.indent += "  "
		for _, d := range x.Elems {
			w.string("\n")
			w.node(d)
			w.string(",")
		}
		w.indent = w.indent[:len(w.indent)-2]
		w.string("\n]")

	case *adt.Field:
		s := w.labelString(x.Label)
		w.string(s)
		w.string(":")
		if x.Label.IsDef() && !internal.IsDef(s) {
			w.string(":")
		}
		w.string(" ")
		w.node(x.Value)

	case *adt.OptionalField:
		s := w.labelString(x.Label)
		w.string(s)
		w.string("?:")
		if x.Label.IsDef() && !internal.IsDef(s) {
			w.string(":")
		}
		w.string(" ")
		w.node(x.Value)

	case *adt.BulkOptionalField:
		w.string("[")
		w.node(x.Filter)
		w.string("]: ")
		w.node(x.Value)

	case *adt.DynamicField:
		w.node(x.Key)
		if x.IsOptional() {
			w.string("?")
		}
		w.string(": ")
		w.node(x.Value)

	case *adt.Ellipsis:
		w.string("...")
		if x.Value != nil {
			w.node(x.Value)
		}

	case *adt.Bottom:
		w.string(`_|_`)
		if x.Err != nil {
			w.string("(")
			w.shortError(x.Err)
			w.string(")")
		}

	case *adt.Null:
		w.string("null")

	case *adt.Bool:
		fmt.Fprint(w, x.B)

	case *adt.Num:
		fmt.Fprint(w, &x.X)

	case *adt.String:
		w.string(strconv.Quote(x.Str))

	case *adt.Bytes:
		b := []byte(strconv.Quote(string(x.B)))
		b[0] = '\''
		b[len(b)-1] = '\''
		w.string(string(b))

	case *adt.Top:
		w.string("_")

	case *adt.BasicType:
		fmt.Fprint(w, x.K)

	case *adt.BoundExpr:
		fmt.Fprint(w, x.Op)
		w.node(x.Expr)

	case *adt.BoundValue:
		fmt.Fprint(w, x.Op)
		w.node(x.Value)

	case *adt.NodeLink:
		w.string(openTuple)
		for i, f := range x.Node.Path() {
			if i > 0 {
				w.string(".")
			}
			w.label(f)
		}
		w.string(closeTuple)

	case *adt.FieldReference:
		w.string(openTuple)
		w.string(strconv.Itoa(int(x.UpCount)))
		w.string(";")
		w.label(x.Label)
		w.string(closeTuple)

	case *adt.LabelReference:
		w.string(openTuple)
		w.string(strconv.Itoa(int(x.UpCount)))
		w.string(";-")
		w.string(closeTuple)

	case *adt.DynamicReference:
		w.string(openTuple)
		w.string(strconv.Itoa(int(x.UpCount)))
		w.string(";(")
		w.node(x.Label)
		w.string(")")
		w.string(closeTuple)

	case *adt.ImportReference:
		w.string(openTuple + "import;")
		w.label(x.ImportPath)
		w.string(closeTuple)

	case *adt.LetReference:
		w.string(openTuple)
		w.string(strconv.Itoa(int(x.UpCount)))
		w.string(";let ")
		w.label(x.Label)
		w.string(closeTuple)

	case *adt.SelectorExpr:
		w.node(x.X)
		w.string(".")
		w.label(x.Sel)

	case *adt.IndexExpr:
		w.node(x.X)
		w.string("[")
		w.node(x.Index)
		w.string("]")

	case *adt.SliceExpr:
		w.node(x.X)
		w.string("[")
		if x.Lo != nil {
			w.node(x.Lo)
		}
		w.string(":")
		if x.Hi != nil {
			w.node(x.Hi)
		}
		if x.Stride != nil {
			w.string(":")
			w.node(x.Stride)
		}
		w.string("]")

	case *adt.Interpolation:
		w.interpolation(x)

	case *adt.UnaryExpr:
		fmt.Fprint(w, x.Op)
		w.node(x.X)

	case *adt.BinaryExpr:
		w.string("(")
		w.node(x.X)
		fmt.Fprint(w, " ", x.Op, " ")
		w.node(x.Y)
		w.string(")")

	case *adt.CallExpr:
		w.node(x.Fun)
		w.string("(")
		for i, a := range x.Args {
			if i > 0 {
				w.string(", ")
			}
			w.node(a)
		}
		w.string(")")

	case *adt.Builtin:
		if x.Package != 0 {
			w.label(x.Package)
			w.string(".")
		}
		w.string(x.Name)

	case *adt.BuiltinValidator:
		w.node(x.Builtin)
		w.string("(")
		for i, a := range x.Args {
			if i > 0 {
				w.string(", ")
			}
			w.node(a)
		}
		w.string(")")

	case *adt.DisjunctionExpr:
		w.string("(")
		for i, a := range x.Values {
			if i > 0 {
				w.string("|")
			}
			// Disjunct
			if a.Default {
				w.string("*")
			}
			w.node(a.Val)
		}
		w.string(")")

	case *adt.Conjunction:
		w.string("&(")
		for i, c := range x.Values {
			if i > 0 {
				w.string(", ")
			}
			w.node(c)
		}
		w.string(")")

	case *adt.Disjunction:
		w.string("|(")
		for i, c := range x.Values {
			if i > 0 {
				w.string(", ")
			}
			if i < x.NumDefaults {
				w.string("*")
			}
			w.node(c)
		}
		w.string(")")

	case *adt.ForClause:
		w.string("for ")
		w.label(x.Key)
		w.string(", ")
		w.label(x.Value)
		w.string(" in ")
		w.node(x.Src)
		w.string(" ")
		w.node(x.Dst)

	case *adt.IfClause:
		w.string("if ")
		w.node(x.Condition)
		w.string(" ")
		w.node(x.Dst)

	case *adt.LetClause:
		w.string("let ")
		w.label(x.Label)
		w.string(" = ")
		w.node(x.Expr)
		w.string(" ")
		w.node(x.Dst)

	case *adt.ValueClause:
		w.node(x.StructLit)

	default:
		panic(fmt.Sprintf("unknown type %T", x))
	}
}
