// Copyright 2018 The 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 cmd

import (
	"bytes"
	"fmt"

	"github.com/spf13/cobra"

	"cuelang.org/go/cue"
	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/format"
	"cuelang.org/go/cue/parser"
)

// newEvalCmd creates a new eval command
func newEvalCmd(c *Command) *cobra.Command {
	cmd := &cobra.Command{
		Use:   "eval",
		Short: "evaluate and print a configuration",
		Long: `eval evaluates, validates, and prints a configuration.

Printing is skipped if validation fails.

The --expression flag is used to evaluate an expression within the
configuration file, instead of the entire configuration file itself.

Examples:

  $ cat <<EOF > foo.cue
  a: [ "a", "b", "c" ]
  EOF

  $ cue eval foo.cue -e a[0] -e a[2]
  "a"
  "c"
`,
		RunE: mkRunE(c, runEval),
	}

	cmd.Flags().StringArrayP(string(flagExpression), "e", nil, "evaluate this expression only")

	cmd.Flags().BoolP(string(flagConcrete), "c", false,
		"require the evaluation to be concrete")

	cmd.Flags().BoolP(string(flagHidden), "H", false,
		"display hidden attributes")

	cmd.Flags().BoolP(string(flagOptional), "O", false,
		"display hidden attributes")

	cmd.Flags().BoolP(string(flagAttributes), "l", false,
		"display field attributes")

	cmd.Flags().BoolP(string(flagAll), "a", false,
		"show optional and hidden fields")

	// TODO: Option to include comments in output.
	return cmd
}

const (
	flagConcrete   flagName = "concrete"
	flagHidden     flagName = "show-hidden"
	flagOptional   flagName = "show-optional"
	flagAttributes flagName = "attributes"
)

func runEval(cmd *Command, args []string) error {
	instances := buildFromArgs(cmd, args)

	var exprs []ast.Expr
	for _, e := range flagExpression.StringArray(cmd) {
		expr, err := parser.ParseExpr("<expression flag>", e)
		if err != nil {
			return err
		}
		exprs = append(exprs, expr)
	}

	w := cmd.OutOrStdout()
	// Always print a trailing newline. format.Node may not write a trailing
	// newline if the output is single-line expression.
	writeNode := func(b []byte, err error) {
		_, _ = w.Write(b)
		if !bytes.HasSuffix(b, []byte("\n")) {
			w.Write([]byte{'\n'})
		}
	}

	for _, inst := range instances {
		// TODO: use ImportPath or some other sanitized path.
		if len(instances) > 1 {
			fmt.Fprintf(w, "\n// %s\n", inst.Dir)
		}
		syn := []cue.Option{
			cue.Attributes(flagAttributes.Bool(cmd)),
			cue.Optional(flagAll.Bool(cmd) || flagOptional.Bool(cmd)),
		}
		if flagConcrete.Bool(cmd) {
			syn = append(syn, cue.Concrete(true))
		}
		if flagHidden.Bool(cmd) || flagAll.Bool(cmd) {
			syn = append(syn, cue.Hidden(true))
		}
		opts := []format.Option{
			format.UseSpaces(4),
			format.TabIndent(false),
		}
		if flagSimplify.Bool(cmd) {
			opts = append(opts, format.Simplify())
		}

		if exprs == nil {
			v := inst.Value()
			if flagConcrete.Bool(cmd) && !flagIgnore.Bool(cmd) {
				if err := v.Validate(cue.Concrete(true)); err != nil {
					exitIfErr(cmd, inst, err, false)
					continue
				}
			}
			writeNode(format.Node(getSyntax(v, syn), opts...))
		}
		for _, e := range exprs {
			if len(exprs) > 1 {
				fmt.Fprint(w, "// ")
				writeNode(format.Node(e))
			}
			v := inst.Eval(e)
			if flagConcrete.Bool(cmd) && !flagIgnore.Bool(cmd) {
				if err := v.Validate(cue.Concrete(true)); err != nil {
					exitIfErr(cmd, inst, err, false)
					continue
				}
			}
			writeNode(format.Node(getSyntax(v, syn), opts...))
		}
	}
	return nil
}

func getSyntax(v cue.Value, opts []cue.Option) ast.Node {
	n := v.Syntax(opts...)
	switch x := n.(type) {
	case *ast.StructLit:
		n = &ast.File{Decls: x.Elts}
	}
	return n
}
