// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package repl

import (
	"fmt"
	"sort"
	"strings"

	"github.com/zclconf/go-cty/cty"

	"github.com/hashicorp/hcl/v2"
	"github.com/hashicorp/hcl/v2/hclsyntax"
	"github.com/hashicorp/terraform/internal/lang"
	"github.com/hashicorp/terraform/internal/lang/marks"
	"github.com/hashicorp/terraform/internal/lang/types"
	"github.com/hashicorp/terraform/internal/tfdiags"
)

// Session represents the state for a single REPL session.
type Session struct {
	// Scope is the evaluation scope where expressions will be evaluated.
	Scope *lang.Scope
}

// Handle handles a single line of input from the REPL.
//
// This is a stateful operation if a command is given (such as setting
// a variable). This function should not be called in parallel.
//
// The return value is the output and the error to show.
func (s *Session) Handle(line string) (string, bool, tfdiags.Diagnostics) {
	switch {
	case strings.TrimSpace(line) == "":
		return "", false, nil
	case strings.TrimSpace(line) == "exit":
		return "", true, nil
	case strings.TrimSpace(line) == "help":
		ret, diags := s.handleHelp()
		return ret, false, diags
	default:
		ret, diags := s.handleEval(line)
		return ret, false, diags
	}
}

func (s *Session) handleEval(line string) (string, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics

	// Parse the given line as an expression
	expr, parseDiags := hclsyntax.ParseExpression([]byte(line), "<console-input>", hcl.Pos{Line: 1, Column: 1})
	diags = diags.Append(parseDiags)
	if parseDiags.HasErrors() {
		return "", diags
	}

	val, valDiags := s.Scope.EvalExpr(expr, cty.DynamicPseudoType)
	diags = diags.Append(valDiags)
	if valDiags.HasErrors() {
		return "", diags
	}

	// The TypeType mark is used only by the console-only `type` function, in
	// order to smuggle the type of a given value back here. We can then
	// display a representation of the type directly.
	if marks.Contains(val, marks.TypeType) {
		val, _ = val.UnmarkDeep()

		valType := val.Type()
		switch {
		case valType.Equals(types.TypeType):
			// An encapsulated type value, which should be displayed directly.
			valType := val.EncapsulatedValue().(*cty.Type)
			return typeString(*valType), diags
		default:
			diags = diags.Append(tfdiags.Sourceless(
				tfdiags.Error,
				"Invalid use of type function",
				"The console-only \"type\" function cannot be used as part of an expression.",
			))
			return "", diags
		}
	}

	return FormatValue(val, 0), diags
}

func (s *Session) handleHelp() (string, tfdiags.Diagnostics) {
	text := `
The Terraform console allows you to experiment with Terraform interpolations.
You may access resources in the state (if you have one) just as you would
from a configuration. For example: "aws_instance.foo.id" would evaluate
to the ID of "aws_instance.foo" if it exists in your state.

Type in the interpolation to test and hit <enter> to see the result.

To exit the console, type "exit" and hit <enter>, or use Control-C or
Control-D.
`

	return strings.TrimSpace(text), nil
}

// Modified copy of TypeString from go-cty:
// https://github.com/zclconf/go-cty-debug/blob/master/ctydebug/type_string.go
//
// TypeString returns a string representation of a given type that is
// reminiscent of Go syntax calling into the cty package but is mainly
// intended for easy human inspection of values in tests, debug output, etc.
//
// The resulting string will include newlines and indentation in order to
// increase the readability of complex structures. It always ends with a
// newline, so you can print this result directly to your output.
func typeString(ty cty.Type) string {
	var b strings.Builder
	writeType(ty, &b, 0)
	return b.String()
}

func writeType(ty cty.Type, b *strings.Builder, indent int) {
	switch {
	case ty == cty.NilType:
		b.WriteString("nil")
		return
	case ty.IsObjectType():
		atys := ty.AttributeTypes()
		if len(atys) == 0 {
			b.WriteString("object({})")
			return
		}
		attrNames := make([]string, 0, len(atys))
		for name := range atys {
			attrNames = append(attrNames, name)
		}
		sort.Strings(attrNames)
		b.WriteString("object({\n")
		indent++
		for _, name := range attrNames {
			aty := atys[name]
			b.WriteString(indentSpaces(indent))
			fmt.Fprintf(b, "%s: ", name)
			writeType(aty, b, indent)
			b.WriteString(",\n")
		}
		indent--
		b.WriteString(indentSpaces(indent))
		b.WriteString("})")
	case ty.IsTupleType():
		etys := ty.TupleElementTypes()
		if len(etys) == 0 {
			b.WriteString("tuple([])")
			return
		}
		b.WriteString("tuple([\n")
		indent++
		for _, ety := range etys {
			b.WriteString(indentSpaces(indent))
			writeType(ety, b, indent)
			b.WriteString(",\n")
		}
		indent--
		b.WriteString(indentSpaces(indent))
		b.WriteString("])")
	case ty.IsCollectionType():
		ety := ty.ElementType()
		switch {
		case ty.IsListType():
			b.WriteString("list(")
		case ty.IsMapType():
			b.WriteString("map(")
		case ty.IsSetType():
			b.WriteString("set(")
		default:
			// At the time of writing there are no other collection types,
			// but we'll be robust here and just pass through the GoString
			// of anything we don't recognize.
			b.WriteString(ty.FriendlyName())
			return
		}
		// Because object and tuple types render split over multiple
		// lines, a collection type container around them can end up
		// being hard to see when scanning, so we'll generate some extra
		// indentation to make a collection of structural type more visually
		// distinct from the structural type alone.
		complexElem := ety.IsObjectType() || ety.IsTupleType()
		if complexElem {
			indent++
			b.WriteString("\n")
			b.WriteString(indentSpaces(indent))
		}
		writeType(ty.ElementType(), b, indent)
		if complexElem {
			indent--
			b.WriteString(",\n")
			b.WriteString(indentSpaces(indent))
		}
		b.WriteString(")")
	default:
		// For any other type we'll just use its GoString and assume it'll
		// follow the usual GoString conventions.
		b.WriteString(ty.FriendlyName())
	}
}

func indentSpaces(level int) string {
	return strings.Repeat("    ", level)
}
