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

package command

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"reflect"
	"regexp"
	"sort"
	"strconv"
	"strings"
	texttemplate "text/template"
	"text/template/parse"

	"github.com/hashicorp/go-multierror"
	"github.com/hashicorp/hcl/v2/hclwrite"
	awscommon "github.com/hashicorp/packer-plugin-amazon/builder/common"
	hcl2shim "github.com/hashicorp/packer-plugin-sdk/hcl2helper"
	"github.com/hashicorp/packer-plugin-sdk/template"
	"github.com/hashicorp/packer/packer"
	"github.com/mitchellh/mapstructure"
	"github.com/posener/complete"
	"github.com/zclconf/go-cty/cty"
)

type HCL2UpgradeCommand struct {
	Meta
}

func (c *HCL2UpgradeCommand) Run(args []string) int {
	ctx, cleanup := handleTermInterrupt(c.Ui)
	defer cleanup()

	cfg, ret := c.ParseArgs(args)
	if ret != 0 {
		return ret
	}

	return c.RunContext(ctx, cfg)
}

func (c *HCL2UpgradeCommand) ParseArgs(args []string) (*HCL2UpgradeArgs, int) {
	var cfg HCL2UpgradeArgs
	flags := c.Meta.FlagSet("hcl2_upgrade", FlagSetNone)
	flags.Usage = func() { c.Ui.Say(c.Help()) }
	cfg.AddFlagSets(flags)
	if err := flags.Parse(args); err != nil {
		return &cfg, 1
	}
	args = flags.Args()
	if len(args) != 1 {
		flags.Usage()
		return &cfg, 1
	}
	cfg.Path = args[0]
	if cfg.OutputFile == "" {
		cfg.OutputFile = cfg.Path + ".pkr.hcl"
	}
	return &cfg, 0
}

const (
	hcl2UpgradeFileHeader = `# This file was autogenerated by the 'packer hcl2_upgrade' command. We
# recommend double checking that everything is correct before going forward. We
# also recommend treating this file as disposable. The HCL2 blocks in this
# file can be moved to other files. For example, the variable blocks could be
# moved to their own 'variables.pkr.hcl' file, etc. Those files need to be
# suffixed with '.pkr.hcl' to be visible to Packer. To use multiple files at
# once they also need to be in the same folder. 'packer inspect folder/'
# will describe to you what is in that folder.

# Avoid mixing go templating calls ( for example ` + "```{{ upper(`string`) }}```" + ` )
# and HCL2 calls (for example '${ var.string_value_example }' ). They won't be
# executed together and the outcome will be unknown.
`
	inputVarHeader = `
# All generated input variables will be of 'string' type as this is how Packer JSON
# views them; you can change their type later on. Read the variables type
# constraints documentation
# https://www.packer.io/docs/templates/hcl_templates/variables#type-constraints for more info.`
	localsVarHeader = `
# All locals variables are generated from variables that uses expressions
# that are not allowed in HCL2 variables.
# Read the documentation for locals blocks here:
# https://www.packer.io/docs/templates/hcl_templates/blocks/locals`
	packerBlockHeader = `
# See https://www.packer.io/docs/templates/hcl_templates/blocks/packer for more info
`

	sourcesHeader = `
# source blocks are generated from your builders; a source can be referenced in
# build blocks. A build block runs provisioner and post-processors on a
# source. Read the documentation for source blocks here:
# https://www.packer.io/docs/templates/hcl_templates/blocks/source`

	buildHeader = `
# a build block invokes sources and runs provisioning steps on them. The
# documentation for build blocks can be found here:
# https://www.packer.io/docs/templates/hcl_templates/blocks/build
`

	amazonAmiDataHeader = `
# The amazon-ami data block is generated from your amazon builder source_ami_filter; a data
# from this block can be referenced in source and locals blocks.
# Read the documentation for data blocks here:
# https://www.packer.io/docs/templates/hcl_templates/blocks/data
# Read the documentation for the Amazon AMI Data Source here:
# https://www.packer.io/plugins/datasources/amazon/ami`

	amazonSecretsManagerDataHeader = `
# The amazon-secretsmanager data block is generated from your aws_secretsmanager template function; a data
# from this block can be referenced in source and locals blocks.
# Read the documentation for data blocks here:
# https://www.packer.io/docs/templates/hcl_templates/blocks/data
# Read the documentation for the Amazon Secrets Manager Data Source here:
# https://www.packer.io/plugins/datasources/amazon/secretsmanager`
)

var (
	amazonSecretsManagerMap = map[string]map[string]interface{}{}
	localsVariableMap       = map[string]string{}
	timestamp               = false
	isotime                 = false
	strftime                = false
)

type BlockParser interface {
	Parse(*template.Template) error
	Write(*bytes.Buffer)
}

func (c *HCL2UpgradeCommand) RunContext(_ context.Context, cla *HCL2UpgradeArgs) int {
	var output io.Writer
	if err := os.MkdirAll(filepath.Dir(cla.OutputFile), 0755); err != nil {
		c.Ui.Error(fmt.Sprintf("Failed to create output directory: %v", err))
		return 1
	}
	if f, err := os.Create(cla.OutputFile); err == nil {
		output = f
		defer f.Close()
	} else {
		c.Ui.Error(fmt.Sprintf("Failed to create output file: %v", err))
		return 1
	}

	if cla.WithAnnotations {
		if _, err := output.Write([]byte(hcl2UpgradeFileHeader)); err != nil {
			c.Ui.Error(fmt.Sprintf("Failed to write to file: %v", err))
			return 1
		}
	}

	hdl, ret := c.GetConfigFromJSON(&cla.MetaArgs)
	if ret != 0 {
		c.Ui.Error("Failed to get config from JSON")
		return 1
	}

	core := hdl.(*packer.Core)
	if err := core.Initialize(packer.InitializeOptions{}); err != nil {
		c.Ui.Error(fmt.Sprintf("Ignoring following initialization error: %v", err))
	}
	tpl := core.Template

	// Parse blocks

	packerBlock := &PackerParser{
		WithAnnotations: cla.WithAnnotations,
	}
	if err := packerBlock.Parse(tpl); err != nil {
		c.Ui.Error(fmt.Sprintf("Ignoring following Parse error: %v", err))
		ret = 1
	}

	variables := &VariableParser{
		WithAnnotations: cla.WithAnnotations,
	}
	if err := variables.Parse(tpl); err != nil {
		c.Ui.Error(fmt.Sprintf("Ignoring following variables.Parse error: %v", err))
		ret = 1
	}

	locals := &LocalsParser{
		LocalsOut:       variables.localsOut,
		WithAnnotations: cla.WithAnnotations,
	}
	if err := locals.Parse(tpl); err != nil {
		c.Ui.Error(fmt.Sprintf("Ignoring following locals.Parse error: %v", err))
		ret = 1
	}

	builders := []*template.Builder{}
	{
		// sort builders to avoid map's randomness
		for _, builder := range tpl.Builders {
			builders = append(builders, builder)
		}
	}
	sort.Slice(builders, func(i, j int) bool {
		return builders[i].Type+builders[i].Name < builders[j].Type+builders[j].Name
	})

	amazonAmiDatasource := &AmazonAmiDatasourceParser{
		Builders:        builders,
		WithAnnotations: cla.WithAnnotations,
	}
	if err := amazonAmiDatasource.Parse(tpl); err != nil {
		c.Ui.Error(fmt.Sprintf("Ignoring following amazonAmiDatasource.Parse error: %v", err))
		ret = 1
	}

	sources := &SourceParser{
		Builders:        builders,
		BuilderPlugins:  c.Meta.CoreConfig.Components.PluginConfig.Builders,
		WithAnnotations: cla.WithAnnotations,
	}
	if err := sources.Parse(tpl); err != nil {
		c.Ui.Error(fmt.Sprintf("Ignoring following sources.Parse error: %v", err))
		ret = 1
	}

	build := &BuildParser{
		Builders:        builders,
		WithAnnotations: cla.WithAnnotations,
	}
	if err := build.Parse(tpl); err != nil {
		c.Ui.Error(fmt.Sprintf("Ignoring following build.Parse error: %v", err))
		ret = 1
	}

	amazonSecretsDatasource := &AmazonSecretsDatasourceParser{
		WithAnnotations: cla.WithAnnotations,
	}
	if err := amazonSecretsDatasource.Parse(tpl); err != nil {
		c.Ui.Error(fmt.Sprintf("Ignoring following amazonSecretsDatasource.Parse error: %v", err))
		ret = 1
	}

	// Write file
	out := &bytes.Buffer{}
	for _, block := range []BlockParser{
		packerBlock,
		variables,
		amazonSecretsDatasource,
		amazonAmiDatasource,
		locals,
		sources,
		build,
	} {
		block.Write(out)
	}

	if _, err := output.Write(hclwrite.Format(out.Bytes())); err != nil {
		c.Ui.Error(fmt.Sprintf("Failed to write to file: %v", err))
		return 1
	}

	c.Ui.Say(fmt.Sprintf("Successfully created %s. Exit %d", cla.OutputFile, ret))
	return ret
}

type UnhandleableArgumentError struct {
	Call           string
	Correspondance string
	Docs           string
}

func (uc UnhandleableArgumentError) Error() string {
	return fmt.Sprintf(`unhandled %q call:
# there is no way to automatically upgrade the %[1]q call.
# Please manually upgrade to %s
# Visit %s for more infos.`, uc.Call, uc.Correspondance, uc.Docs)
}

func fallbackReturn(err error, s []byte) []byte {
	if strings.Contains(err.Error(), "unhandled") {
		return append([]byte(fmt.Sprintf("\n# %s\n", err)), s...)
	}

	return append([]byte(fmt.Sprintf("\n# could not parse template for following block: %q\n", err)), s...)
}

// reTemplate writes a new template to `out` and escapes all unknown variables
// so that we don't interpret them later on when interpreting the template
func reTemplate(nd parse.Node, out io.Writer, funcs texttemplate.FuncMap) error {
	switch node := nd.(type) {
	case *parse.ActionNode:
		// Leave pipes as-is
		if len(node.Pipe.Cmds) > 1 {
			fmt.Fprintf(out, "%s", node.String())
			return nil
		}

		cmd := node.Pipe.Cmds[0]
		args := cmd.Args
		if len(args) > 1 {
			// Function calls with parameters are left aside
			fmt.Fprintf(out, "%s", node.String())
			return nil
		}

		_, ok := funcs[args[0].String()]
		if ok {
			// Known functions left as-is
			fmt.Fprintf(out, "%s", node.String())
			return nil
		}

		// Escape anything that isn't in the func map
		fmt.Fprintf(out, "{{ \"{{\" }} %s {{ \"}}\" }}", cmd.String())

	// TODO maybe node.Pipe.Decls? Though in Packer templates they're not
	// supported officially so they can be left aside for now
	case *parse.ListNode:
		for _, child := range node.Nodes {
			err := reTemplate(child, out, funcs)
			if err != nil {
				return err
			}
		}
	case *parse.TextNode:
		_, err := fmt.Fprintf(out, "%s", node.Text)
		if err != nil {
			return err
		}
	default:
		return fmt.Errorf("unhandled node type %s", reflect.TypeOf(nd))
	}
	return nil
}

// transposeTemplatingCalls executes parts of blocks as go template files and replaces
// their result with their hcl2 variant. If something goes wrong the template
// containing the go template string is returned.
func transposeTemplatingCalls(s []byte) []byte {
	funcErrors := &multierror.Error{
		ErrorFormat: func(es []error) string {
			if len(es) == 1 {
				return fmt.Sprintf("# 1 error occurred upgrading the following block:\n\t# %s\n", es[0])
			}

			points := make([]string, len(es))
			for i, err := range es {
				if i == len(es)-1 {
					points[i] = fmt.Sprintf("# %s", err)
					continue
				}
				points[i] = fmt.Sprintf("# %s\n", err)
			}

			return fmt.Sprintf(
				"# %d errors occurred upgrading the following block:\n\t%s",
				len(es), strings.Join(points, "\n\t"))
		},
	}

	funcMap := texttemplate.FuncMap{
		"aws_secretsmanager": func(a ...string) string {
			if len(a) == 2 {
				for key, config := range amazonSecretsManagerMap {
					nameOk := config["name"] == a[0]
					keyOk := config["key"] == a[1]
					if nameOk && keyOk {
						return fmt.Sprintf("${data.amazon-secretsmanager.%s.value}", key)
					}
				}
				id := fmt.Sprintf("autogenerated_%d", len(amazonSecretsManagerMap)+1)
				amazonSecretsManagerMap[id] = map[string]interface{}{
					"name": a[0],
					"key":  a[1],
				}
				return fmt.Sprintf("${data.amazon-secretsmanager.%s.value}", id)
			}
			for key, config := range amazonSecretsManagerMap {
				nameOk := config["name"] == a[0]
				if nameOk {
					return fmt.Sprintf("${data.amazon-secretsmanager.%s.value}", key)
				}
			}
			id := fmt.Sprintf("autogenerated_%d", len(amazonSecretsManagerMap)+1)
			amazonSecretsManagerMap[id] = map[string]interface{}{
				"name": a[0],
			}
			return fmt.Sprintf("${data.amazon-secretsmanager.%s.value}", id)
		},
		"timestamp": func() string {
			timestamp = true
			return "${local.timestamp}"
		},
		"isotime": func(a ...string) string {
			if len(a) == 0 {
				// returns rfc3339 formatted string.
				return "${timestamp()}"
			}
			// otherwise a valid isotime func has one input.
			isotime = true
			return fmt.Sprintf("${legacy_isotime(\"%s\")}", a[0])

		},
		"strftime": func(a ...string) string {
			if len(a) == 0 {
				// returns rfc3339 formatted string.
				return "${timestamp()}"
			}
			strftime = true
			return fmt.Sprintf("${legacy_strftime(\"%s\")}", a[0])
		},
		"user": func(in string) string {
			if _, ok := localsVariableMap[in]; ok {
				// variable is now a local
				return fmt.Sprintf("${local.%s}", in)
			}
			return fmt.Sprintf("${var.%s}", in)
		},
		"env": func(in string) string {
			return fmt.Sprintf("${env(%q)}", in)
		},
		"build": func(a string) string {
			return fmt.Sprintf("${build.%s}", a)
		},
		"data": func(a string) string {
			return fmt.Sprintf("${data.%s}", a)
		},
		"template_dir": func() string {
			return "${path.root}"
		},
		"pwd": func() string {
			return "${path.cwd}"
		},
		"packer_version": func() string {
			return "${packer.version}"
		},
		"uuid": func() string {
			return "${uuidv4()}"
		},
		"lower": func(a string) (string, error) {
			funcErrors = multierror.Append(funcErrors, UnhandleableArgumentError{
				"lower",
				"`lower(var.example)`",
				"https://www.packer.io/docs/templates/hcl_templates/functions/string/lower",
			})
			return fmt.Sprintf("{{ lower `%s` }}", a), nil
		},
		"upper": func(a string) (string, error) {
			funcErrors = multierror.Append(funcErrors, UnhandleableArgumentError{
				"upper",
				"`upper(var.example)`",
				"https://www.packer.io/docs/templates/hcl_templates/functions/string/upper",
			})
			return fmt.Sprintf("{{ upper `%s` }}", a), nil
		},
		"split": func(a, b string, n int) (string, error) {
			funcErrors = multierror.Append(funcErrors, UnhandleableArgumentError{
				"split",
				"`split(separator, string)`",
				"https://www.packer.io/docs/templates/hcl_templates/functions/string/split",
			})
			return fmt.Sprintf("{{ split `%s` `%s` %d }}", a, b, n), nil
		},
		"replace": func(a, b string, n int, c string) (string, error) {
			funcErrors = multierror.Append(funcErrors, UnhandleableArgumentError{
				"replace",
				"`replace(string, substring, replacement)` or `regex_replace(string, substring, replacement)`",
				"https://www.packer.io/docs/templates/hcl_templates/functions/string/replace or https://www.packer.io/docs/templates/hcl_templates/functions/string/regex_replace",
			})
			return fmt.Sprintf("{{ replace `%s` `%s` `%s` %d }}", a, b, c, n), nil
		},
		"replace_all": func(a, b, c string) (string, error) {
			funcErrors = multierror.Append(funcErrors, UnhandleableArgumentError{
				"replace_all",
				"`replace(string, substring, replacement)` or `regex_replace(string, substring, replacement)`",
				"https://www.packer.io/docs/templates/hcl_templates/functions/string/replace or https://www.packer.io/docs/templates/hcl_templates/functions/string/regex_replace",
			})
			return fmt.Sprintf("{{ replace_all `%s` `%s` `%s` }}", a, b, c), nil
		},
		"clean_resource_name": func(a string) (string, error) {
			funcErrors = multierror.Append(funcErrors, UnhandleableArgumentError{
				"clean_resource_name",
				"use custom validation rules, `replace(string, substring, replacement)` or `regex_replace(string, substring, replacement)`",
				"https://packer.io/docs/templates/hcl_templates/variables#custom-validation-rules" +
					" , https://www.packer.io/docs/templates/hcl_templates/functions/string/replace" +
					" or https://www.packer.io/docs/templates/hcl_templates/functions/string/regex_replace",
			})
			return fmt.Sprintf("{{ clean_resource_name `%s` }}", a), nil
		},
		"build_name": func() string {
			return "${build.name}"
		},
		"build_type": func() string {
			return "${build.type}"
		},
	}

	tpl, err := texttemplate.New("hcl2_upgrade").
		Funcs(funcMap).
		Parse(string(s))

	if err != nil {
		if strings.Contains(err.Error(), "unexpected \"\\\\\" in operand") {
			// This error occurs if the operand in the text template used
			// escaped quoting \" instead of bactick quoting `
			// Create a regex to do a string replace on this block, to fix
			// quoting.
			q := fixQuoting(string(s))
			unquoted := []byte(q)
			tpl, err = texttemplate.New("hcl2_upgrade").
				Funcs(funcMap).
				Parse(string(unquoted))
			if err != nil {
				return fallbackReturn(err, unquoted)
			}
		} else {
			return fallbackReturn(err, s)
		}
	}

	retempl := &bytes.Buffer{}
	if err := reTemplate(tpl.Root, retempl, funcMap); err != nil {
		return fallbackReturn(err, s)
	}

	tpl, err = texttemplate.New("hcl2_upgrade").
		Funcs(funcMap).
		Parse(retempl.String())

	str := &bytes.Buffer{}

	if err := tpl.Execute(str, nil); err != nil {
		return fallbackReturn(err, s)
	}

	out := str.Bytes()

	if funcErrors.Len() > 0 {
		return append([]byte(fmt.Sprintf("\n%s", funcErrors)), out...)
	}
	return out
}

// variableTransposeTemplatingCalls executes parts of blocks as go template files and replaces
// their result with their hcl2 variant for variables block only. If something goes wrong the template
// containing the go template string is returned.
// In variableTransposeTemplatingCalls the definition of aws_secretsmanager function will create a data source
// with the same name as the variable.
func variableTransposeTemplatingCalls(s []byte) (isLocal bool, body []byte) {
	setIsLocal := func(a ...string) string {
		isLocal = true
		return ""
	}

	// Make locals from variables using valid template engine,
	// expect the ones using only 'env'
	// ref: https://www.packer.io/docs/templates/legacy_json_templates/engine#template-engine
	funcMap := texttemplate.FuncMap{
		"aws_secretsmanager": setIsLocal,
		"timestamp":          setIsLocal,
		"isotime":            setIsLocal,
		"strftime":           setIsLocal,
		"user":               setIsLocal,
		"env": func(in string) string {
			return fmt.Sprintf("${env(%q)}", in)
		},
		"template_dir":   setIsLocal,
		"pwd":            setIsLocal,
		"packer_version": setIsLocal,
		"uuid":           setIsLocal,
		"lower":          setIsLocal,
		"upper":          setIsLocal,
		"split": func(_, _ string, _ int) (string, error) {
			isLocal = true
			return "", nil
		},
		"replace": func(_, _ string, _ int, _ string) (string, error) {
			isLocal = true
			return "", nil
		},
		"replace_all": func(_, _, _ string) (string, error) {
			isLocal = true
			return "", nil
		},
	}

	tpl, err := texttemplate.New("hcl2_upgrade").
		Funcs(funcMap).
		Parse(string(s))

	if err != nil {
		if strings.Contains(err.Error(), "unexpected \"\\\\\" in operand") {
			// This error occurs if the operand in the text template used
			// escaped quoting \" instead of bactick quoting `
			// Create a regex to do a string replace on this block, to fix
			// quoting.
			q := fixQuoting(string(s))
			unquoted := []byte(q)
			tpl, err = texttemplate.New("hcl2_upgrade").
				Funcs(funcMap).
				Parse(string(unquoted))
			if err != nil {
				return isLocal, fallbackReturn(err, unquoted)
			}
		} else {
			return isLocal, fallbackReturn(err, s)
		}
	}

	retempl := &bytes.Buffer{}
	if err := reTemplate(tpl.Root, retempl, funcMap); err != nil {
		return isLocal, fallbackReturn(err, s)
	}

	tpl, err = texttemplate.New("hcl2_upgrade").
		Funcs(funcMap).
		Parse(retempl.String())

	str := &bytes.Buffer{}
	if err := tpl.Execute(str, nil); err != nil {
		return isLocal, fallbackReturn(err, s)
	}

	return isLocal, str.Bytes()
}

// referencedUserVariables executes parts of blocks as go template files finding user variables referenced
// within the template. This function should be called once to extract those variables referenced via the {{user `...`}}
// template function. The resulting map will contain variables defined in the JSON variables property, and some that
// are declared via var-files; to avoid duplicates the results of this function should be reconciled against tpl.Variables.
func referencedUserVariables(s []byte) map[string]*template.Variable {
	userVars := make([]string, 0)
	funcMap := texttemplate.FuncMap{
		"user": func(in string) string {
			userVars = append(userVars, in)
			return ""
		},
	}

	tpl, err := texttemplate.New("hcl2_upgrade").
		Funcs(funcMap).
		Parse(string(s))
	if err != nil {
		return nil
	}

	if err := tpl.Execute(&bytes.Buffer{}, nil); err != nil {
		return nil
	}

	vars := make(map[string]*template.Variable)
	for _, v := range userVars {
		vars[v] = &template.Variable{
			Key:      v,
			Required: true,
		}
	}
	return vars
}

func jsonBodyToHCL2Body(out *hclwrite.Body, kvs map[string]interface{}) {
	ks := []string{}
	for k := range kvs {
		ks = append(ks, k)
	}
	sort.Strings(ks)

	for _, k := range ks {
		value := kvs[k]

		switch value := value.(type) {
		case map[string]interface{}:
			var mostComplexElem interface{}
			for _, randomElem := range value {
				if k == "linux_options" || k == "network_interface" || k == "shared_image_gallery" {
					break
				}
				// HACK: we take the most complex element of that map because
				// in HCL2, map of objects can be bodies, for example:
				// map containing object: source_ami_filter {} ( body )
				// simple string/string map: tags = {} ) ( attribute )
				//
				// if we could not find an object in this map then it's most
				// likely a plain map and so we guess it should be and
				// attribute. Though now if value refers to something that is
				// an object but only contains a string or a bool; we could
				// generate a faulty object. For example a (somewhat invalid)
				// source_ami_filter where only `most_recent` is set.
				switch randomElem.(type) {
				case string, int, float64, bool:
					if mostComplexElem != nil {
						continue
					}
					mostComplexElem = randomElem
				default:
					mostComplexElem = randomElem
				}
			}

			switch mostComplexElem.(type) {
			case string, int, float64, bool:
				out.SetAttributeValue(k, hcl2shim.HCL2ValueFromConfigValue(value))
			default:
				nestedBlockBody := out.AppendNewBlock(k, nil).Body()
				jsonBodyToHCL2Body(nestedBlockBody, value)
			}
		case map[string]string, map[string]int, map[string]float64:
			out.SetAttributeValue(k, hcl2shim.HCL2ValueFromConfigValue(value))
		case []interface{}:
			if len(value) == 0 {
				continue
			}

			var mostComplexElem interface{}
			for _, randomElem := range value {
				// HACK: we take the most complex element of that slice because
				// in hcl2 slices of plain types can be arrays, for example:
				// simple string type: owners = ["0000000000"]
				// object: launch_block_device_mappings {}
				switch randomElem.(type) {
				case string, int, float64, bool:
					if mostComplexElem != nil {
						continue
					}
					mostComplexElem = randomElem
				default:
					mostComplexElem = randomElem
				}
			}
			switch mostComplexElem.(type) {
			case map[string]interface{}:
				// this is an object in a slice; so we unwrap it. We
				// could try to remove any 's' suffix in the key, but
				// this might not work everywhere.
				for i := range value {
					value := value[i].(map[string]interface{})
					nestedBlockBody := out.AppendNewBlock(k, nil).Body()
					jsonBodyToHCL2Body(nestedBlockBody, value)
				}
				continue
			default:
				out.SetAttributeValue(k, hcl2shim.HCL2ValueFromConfigValue(value))
			}
		default:
			out.SetAttributeValue(k, hcl2shim.HCL2ValueFromConfigValue(value))
		}
	}
}

func isSensitiveVariable(key string, vars []*template.Variable) bool {
	for _, v := range vars {
		if v.Key == key {
			return true
		}
	}
	return false
}

func (*HCL2UpgradeCommand) Help() string {
	helpText := `
Usage: packer hcl2_upgrade [options] TEMPLATE

  Will transform your JSON template into an HCL2 configuration.

Options:

  -output-file=path    Set output file name. By default this will be the
                       TEMPLATE name with ".pkr.hcl" appended to it. To be a
                       valid Packer HCL template, it must have the suffix
                       ".pkr.hcl"
  -with-annotations    Add helper annotation comments to the file to help new
                       HCL2 users understand the template format.
`

	return strings.TrimSpace(helpText)
}

func (*HCL2UpgradeCommand) Synopsis() string {
	return "transform a JSON template into an HCL2 configuration"
}

func (*HCL2UpgradeCommand) AutocompleteArgs() complete.Predictor {
	return complete.PredictNothing
}

func (*HCL2UpgradeCommand) AutocompleteFlags() complete.Flags {
	return complete.Flags{}
}

// Specific blocks parser responsible to parse and write the block

type PackerParser struct {
	WithAnnotations bool
	out             []byte
}

func (p *PackerParser) Parse(tpl *template.Template) error {
	reqPlugins, err := p.generateRequiredPluginsBlock(tpl)
	if err != nil {
		return err
	}

	if tpl.MinVersion == "" && reqPlugins == nil {
		return nil
	}

	fileContent := hclwrite.NewEmptyFile()
	body := fileContent.Body()
	packerBody := body.AppendNewBlock("packer", nil).Body()

	if tpl.MinVersion != "" {
		packerBody.SetAttributeValue("required_version", cty.StringVal(fmt.Sprintf(">= %s", tpl.MinVersion)))
	}

	if reqPlugins != nil {
		packerBody.AppendBlock(reqPlugins)
	}

	p.out = fileContent.Bytes()

	return nil
}

func gatherPluginsFromTemplate(tpl *template.Template) []string {
	plugins := map[string]struct{}{}

	for _, b := range tpl.Builders {
		for prefix, plugin := range knownPluginPrefixes {
			if strings.HasPrefix(b.Type, prefix) {
				plugins[plugin] = struct{}{}
			}
		}
	}

	for _, p := range tpl.Provisioners {
		for prefix, plugin := range knownPluginPrefixes {
			if strings.HasPrefix(p.Type, prefix) {
				plugins[plugin] = struct{}{}
			}
		}
	}

	for _, pps := range tpl.PostProcessors {
		for _, pp := range pps {
			for prefix, plugin := range knownPluginPrefixes {
				if strings.HasPrefix(pp.Type, prefix) {
					plugins[plugin] = struct{}{}
				}
			}
		}
	}

	if len(plugins) == 0 {
		return nil
	}

	retPlugins := make([]string, 0, len(plugins))
	for plugin := range plugins {
		retPlugins = append(retPlugins, plugin)
	}

	sort.Strings(retPlugins)

	return retPlugins
}

func (p *PackerParser) generateRequiredPluginsBlock(tpl *template.Template) (*hclwrite.Block, error) {
	plugins := gatherPluginsFromTemplate(tpl)
	if len(plugins) == 0 {
		return nil, nil
	}

	reqPlugins := hclwrite.NewBlock("required_plugins", nil)
	for _, plugin := range plugins {
		pluginBlock := cty.ObjectVal(map[string]cty.Value{
			"source":  cty.StringVal(plugin),
			"version": cty.StringVal("~> 1"),
		})
		reqPlugins.Body().SetAttributeValue(strings.Replace(plugin, "github.com/hashicorp/", "", 1), pluginBlock)
	}

	return reqPlugins, nil
}

func (p *PackerParser) Write(out *bytes.Buffer) {
	if len(p.out) > 0 {
		if p.WithAnnotations {
			out.Write([]byte(packerBlockHeader))
		}
		out.Write(p.out)
	}
}

type VariableParser struct {
	WithAnnotations bool
	variablesOut    []byte
	localsOut       []byte
}

func makeLocal(variable *template.Variable, sensitive bool, localBody *hclwrite.Body, localsContent *hclwrite.File, hasLocals *bool) []byte {
	if sensitive {
		// Create Local block because this is sensitive
		sensitiveLocalContent := hclwrite.NewEmptyFile()
		body := sensitiveLocalContent.Body()
		body.AppendNewline()
		sensitiveLocalBody := body.AppendNewBlock("local", []string{variable.Key}).Body()
		sensitiveLocalBody.SetAttributeValue("sensitive", cty.BoolVal(true))
		sensitiveLocalBody.SetAttributeValue("expression", hcl2shim.HCL2ValueFromConfigValue(variable.Default))
		localsVariableMap[variable.Key] = "local"
		return sensitiveLocalContent.Bytes()
	}
	localBody.SetAttributeValue(variable.Key, hcl2shim.HCL2ValueFromConfigValue(variable.Default))
	localsVariableMap[variable.Key] = "locals"
	*hasLocals = true
	return []byte{}
}

func makeVariable(variable *template.Variable, sensitive bool) []byte {
	variablesContent := hclwrite.NewEmptyFile()
	variablesBody := variablesContent.Body()
	variablesBody.AppendNewline()
	variableBody := variablesBody.AppendNewBlock("variable", []string{variable.Key}).Body()
	variableBody.SetAttributeRaw("type", hclwrite.Tokens{&hclwrite.Token{Bytes: []byte("string")}})

	if variable.Default != "" || !variable.Required {
		shimmed := hcl2shim.HCL2ValueFromConfigValue(variable.Default)
		variableBody.SetAttributeValue("default", shimmed)
	}
	if sensitive {
		variableBody.SetAttributeValue("sensitive", cty.BoolVal(true))
	}

	return variablesContent.Bytes()
}

func (p *VariableParser) Parse(tpl *template.Template) error {
	// Output Locals and Local blocks
	localsContent := hclwrite.NewEmptyFile()
	localsBody := localsContent.Body()
	localsBody.AppendNewline()
	localBody := localsBody.AppendNewBlock("locals", nil).Body()
	hasLocals := false

	if len(p.variablesOut) == 0 {
		p.variablesOut = []byte{}
	}
	if len(p.localsOut) == 0 {
		p.localsOut = []byte{}
	}

	if len(tpl.Variables) == 0 {
		tpl.Variables = make(map[string]*template.Variable)
	}
	// JSON supports variable declaration via var-files.
	// User variables that might be defined in a var-file
	// but not in the actual JSON template should be accounted for.
	userVars := referencedUserVariables(tpl.RawContents)
	for name, variable := range userVars {
		if _, ok := tpl.Variables[name]; ok {
			continue
		}
		tpl.Variables[name] = variable
	}

	variables := []*template.Variable{}
	{
		// sort variables to avoid map's randomness
		for _, variable := range tpl.Variables {
			variables = append(variables, variable)
		}
		sort.Slice(variables, func(i, j int) bool {
			return variables[i].Key < variables[j].Key
		})
	}

	for _, variable := range variables {
		// Create new HCL2 "variables" block, and populate the "value"
		// field with the "Default" value from the JSON variable.

		// Interpolate Jsonval first as an hcl variable to determine if it is
		// a local. Variables referencing some form of variable expression must be defined as a local in HCL2,
		// as variables in HCL2 must have a known value at parsing time.
		isLocal, _ := variableTransposeTemplatingCalls([]byte(variable.Default))
		sensitive := false
		if isSensitiveVariable(variable.Key, tpl.SensitiveVariables) {
			sensitive = true
		}
		// Create final HCL block and append.
		if isLocal {
			sensitiveBlocks := makeLocal(variable, sensitive, localBody, localsContent, &hasLocals)
			if len(sensitiveBlocks) > 0 {
				p.localsOut = append(p.localsOut, transposeTemplatingCalls(sensitiveBlocks)...)
			}
			continue
		}
		varbytes := makeVariable(variable, sensitive)
		_, out := variableTransposeTemplatingCalls(varbytes)
		p.variablesOut = append(p.variablesOut, out...)
	}

	if hasLocals == true {
		p.localsOut = append(p.localsOut, transposeTemplatingCalls(localsContent.Bytes())...)
	}

	return nil
}

func (p *VariableParser) Write(out *bytes.Buffer) {
	if len(p.variablesOut) > 0 {
		if p.WithAnnotations {
			out.Write([]byte(inputVarHeader))
		}
		out.Write(p.variablesOut)
	}
}

type LocalsParser struct {
	WithAnnotations bool
	LocalsOut       []byte
}

func (p *LocalsParser) Parse(tpl *template.Template) error {
	// Locals where parsed with Variables
	return nil
}

func (p *LocalsParser) Write(out *bytes.Buffer) {
	if timestamp {
		_, _ = out.Write([]byte("\n"))
		if p.WithAnnotations {
			fmt.Fprintln(out, `# "timestamp" template function replacement`)
		}
		fmt.Fprintln(out, `locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") }`)
	}
	if isotime {
		fmt.Fprintln(out, `# The "legacy_isotime" function has been provided for backwards compatability, but we recommend switching to the timestamp and formatdate functions.`)
	}
	if strftime {
		fmt.Fprintln(out, `# The "legacy_strftime" function has been provided for backwards compatability, but we recommend switching to the timestamp and formatdate functions.`)
	}
	if len(p.LocalsOut) > 0 {
		if p.WithAnnotations {
			out.Write([]byte(localsVarHeader))
		}
		out.Write(p.LocalsOut)
	}
}

type AmazonSecretsDatasourceParser struct {
	WithAnnotations bool
	out             []byte
}

func (p *AmazonSecretsDatasourceParser) Parse(_ *template.Template) error {
	if p.out == nil {
		p.out = []byte{}
	}

	keys := make([]string, 0, len(amazonSecretsManagerMap))
	for k := range amazonSecretsManagerMap {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	for _, dataSourceName := range keys {
		datasourceContent := hclwrite.NewEmptyFile()
		body := datasourceContent.Body()
		body.AppendNewline()
		datasourceBody := body.AppendNewBlock("data", []string{"amazon-secretsmanager", dataSourceName}).Body()
		jsonBodyToHCL2Body(datasourceBody, amazonSecretsManagerMap[dataSourceName])
		p.out = append(p.out, datasourceContent.Bytes()...)
	}

	return nil
}

func (p *AmazonSecretsDatasourceParser) Write(out *bytes.Buffer) {
	if len(p.out) > 0 {
		if p.WithAnnotations {
			out.Write([]byte(amazonSecretsManagerDataHeader))
		}
		out.Write(p.out)
	}
}

type AmazonAmiDatasourceParser struct {
	Builders        []*template.Builder
	WithAnnotations bool
	out             []byte
}

func (p *AmazonAmiDatasourceParser) Parse(_ *template.Template) error {
	if p.out == nil {
		p.out = []byte{}
	}

	amazonAmiFilters := []map[string]interface{}{}
	i := 1
	for _, builder := range p.Builders {
		if strings.HasPrefix(builder.Type, "amazon-") {
			if sourceAmiFilter, ok := builder.Config["source_ami_filter"]; ok {
				sourceAmiFilterCfg := map[string]interface{}{}
				if err := mapstructure.Decode(sourceAmiFilter, &sourceAmiFilterCfg); err != nil {
					return fmt.Errorf("Failed to write amazon-ami data source: %v", err)
				}

				sourceAmiFilterCfg, err := copyAWSAccessConfig(sourceAmiFilterCfg, builder.Config)
				if err != nil {
					return err
				}

				duplicate := false
				dataSourceName := fmt.Sprintf("autogenerated_%d", i)
				for j, filter := range amazonAmiFilters {
					if reflect.DeepEqual(filter, sourceAmiFilterCfg) {
						duplicate = true
						dataSourceName = fmt.Sprintf("autogenerated_%d", j+1)
						continue
					}
				}

				// This is a hack...
				// Use templating so that it could be correctly transformed later into a data resource
				sourceAmiDataRef := fmt.Sprintf("{{ data `amazon-ami.%s.id` }}", dataSourceName)

				if duplicate {
					delete(builder.Config, "source_ami_filter")
					builder.Config["source_ami"] = sourceAmiDataRef
					continue
				}

				amazonAmiFilters = append(amazonAmiFilters, sourceAmiFilterCfg)
				delete(builder.Config, "source_ami_filter")
				builder.Config["source_ami"] = sourceAmiDataRef
				i++

				datasourceContent := hclwrite.NewEmptyFile()
				body := datasourceContent.Body()
				body.AppendNewline()
				sourceBody := body.AppendNewBlock("data", []string{"amazon-ami", dataSourceName}).Body()
				jsonBodyToHCL2Body(sourceBody, sourceAmiFilterCfg)
				p.out = append(p.out, transposeTemplatingCalls(datasourceContent.Bytes())...)
			}
		}
	}
	return nil
}

func copyAWSAccessConfig(sourceAmi map[string]interface{}, builder map[string]interface{}) (map[string]interface{}, error) {
	// Transform access config to a map
	accessConfigMap := map[string]interface{}{}
	if err := mapstructure.Decode(awscommon.AccessConfig{}, &accessConfigMap); err != nil {
		return sourceAmi, err
	}

	for k := range accessConfigMap {
		// Copy only access config present in the builder
		if v, ok := builder[k]; ok {
			sourceAmi[k] = v
		}
	}

	return sourceAmi, nil
}

func (p *AmazonAmiDatasourceParser) Write(out *bytes.Buffer) {
	if len(p.out) > 0 {
		if p.WithAnnotations {
			out.Write([]byte(amazonAmiDataHeader))
		}
		out.Write(p.out)
	}
}

type SourceParser struct {
	Builders        []*template.Builder
	BuilderPlugins  packer.BuilderSet
	WithAnnotations bool
	out             []byte
}

func (p *SourceParser) Parse(tpl *template.Template) error {
	var unknownBuilders []string
	if p.out == nil {
		p.out = []byte{}
	}
	for i, builderCfg := range p.Builders {
		sourcesContent := hclwrite.NewEmptyFile()
		body := sourcesContent.Body()

		body.AppendNewline()
		if !p.BuilderPlugins.Has(builderCfg.Type) {
			unknownBuilders = append(unknownBuilders, builderCfg.Type)

		}
		if builderCfg.Name == "" || builderCfg.Name == builderCfg.Type {
			builderCfg.Name = fmt.Sprintf("autogenerated_%d", i+1)
		}
		builderCfg.Name = strings.ReplaceAll(strings.TrimSpace(builderCfg.Name), " ", "_")

		sourceBody := body.AppendNewBlock("source", []string{builderCfg.Type, builderCfg.Name}).Body()

		jsonBodyToHCL2Body(sourceBody, builderCfg.Config)

		p.out = append(p.out, transposeTemplatingCalls(sourcesContent.Bytes())...)
	}
	if len(unknownBuilders) > 0 {
		return fmt.Errorf("unknown builder type(s): %v\n", unknownBuilders)
	}
	return nil
}

func (p *SourceParser) Write(out *bytes.Buffer) {
	if len(p.out) > 0 {
		if p.WithAnnotations {
			out.Write([]byte(sourcesHeader))
		}
		out.Write(p.out)
	}
}

type BuildParser struct {
	Builders        []*template.Builder
	WithAnnotations bool

	provisioners   BlockParser
	postProcessors BlockParser
	out            []byte
}

func (p *BuildParser) Parse(tpl *template.Template) error {
	if len(p.Builders) == 0 {
		return nil
	}

	buildContent := hclwrite.NewEmptyFile()
	buildBody := buildContent.Body()
	if tpl.Description != "" {
		buildBody.SetAttributeValue("description", cty.StringVal(tpl.Description))
		buildBody.AppendNewline()
	}

	sourceNames := []string{}
	for _, builder := range p.Builders {
		sourceNames = append(sourceNames, fmt.Sprintf("source.%s.%s", builder.Type, builder.Name))
	}
	buildBody.SetAttributeValue("sources", hcl2shim.HCL2ValueFromConfigValue(sourceNames))
	buildBody.AppendNewline()
	p.out = buildContent.Bytes()

	p.provisioners = &ProvisionerParser{
		WithAnnotations: p.WithAnnotations,
	}
	if err := p.provisioners.Parse(tpl); err != nil {
		return err
	}

	p.postProcessors = &PostProcessorParser{
		WithAnnotations: p.WithAnnotations,
	}
	if err := p.postProcessors.Parse(tpl); err != nil {
		return err
	}

	return nil
}

func (p *BuildParser) Write(out *bytes.Buffer) {
	if len(p.out) > 0 {
		if p.WithAnnotations {
			out.Write([]byte(buildHeader))
		} else {
			_, _ = out.Write([]byte("\n"))
		}
		_, _ = out.Write([]byte("build {\n"))
		out.Write(p.out)
		p.provisioners.Write(out)
		p.postProcessors.Write(out)
		_, _ = out.Write([]byte("}\n"))
	}
}

type ProvisionerParser struct {
	WithAnnotations bool
	out             []byte
}

func (p *ProvisionerParser) Parse(tpl *template.Template) error {
	if p.out == nil {
		p.out = []byte{}
	}
	for _, provisioner := range tpl.Provisioners {
		contentBytes := writeProvisioner("provisioner", provisioner)
		p.out = append(p.out, transposeTemplatingCalls(contentBytes)...)
	}

	if tpl.CleanupProvisioner != nil {
		contentBytes := writeProvisioner("error-cleanup-provisioner", tpl.CleanupProvisioner)
		p.out = append(p.out, transposeTemplatingCalls(contentBytes)...)
	}
	return nil
}

func writeProvisioner(typeName string, provisioner *template.Provisioner) []byte {
	provisionerContent := hclwrite.NewEmptyFile()
	body := provisionerContent.Body()
	block := body.AppendNewBlock(typeName, []string{provisioner.Type})

	cfg := provisioner.Config
	if cfg == nil {
		cfg = map[string]interface{}{}
	}

	if len(provisioner.Except) > 0 {
		cfg["except"] = provisioner.Except
	}
	if len(provisioner.Only) > 0 {
		cfg["only"] = provisioner.Only
	}
	if provisioner.MaxRetries != "" {
		cfg["max_retries"] = provisioner.MaxRetries
	}
	if provisioner.Timeout > 0 {
		cfg["timeout"] = provisioner.Timeout.String()
	}
	if provisioner.PauseBefore > 0 {
		cfg["pause_before"] = provisioner.PauseBefore.String()
	}
	body.AppendNewline()
	jsonBodyToHCL2Body(block.Body(), cfg)
	return provisionerContent.Bytes()
}

func (p *ProvisionerParser) Write(out *bytes.Buffer) {
	if len(p.out) > 0 {
		out.Write(p.out)
	}
}

type PostProcessorParser struct {
	WithAnnotations bool
	out             []byte
}

func (p *PostProcessorParser) Parse(tpl *template.Template) error {
	if p.out == nil {
		p.out = []byte{}
	}
	for _, pps := range tpl.PostProcessors {
		postProcessorContent := hclwrite.NewEmptyFile()
		body := postProcessorContent.Body()

		switch len(pps) {
		case 0:
			continue
		case 1:
		default:
			body = body.AppendNewBlock("post-processors", nil).Body()
		}
		for _, pp := range pps {
			ppBody := body.AppendNewBlock("post-processor", []string{pp.Type}).Body()
			if pp.KeepInputArtifact != nil {
				ppBody.SetAttributeValue("keep_input_artifact", cty.BoolVal(*pp.KeepInputArtifact))
			}
			cfg := pp.Config
			if cfg == nil {
				cfg = map[string]interface{}{}
			}

			if len(pp.Except) > 0 {
				cfg["except"] = pp.Except
			}
			if len(pp.Only) > 0 {
				cfg["only"] = pp.Only
			}
			if pp.Name != "" && pp.Name != pp.Type {
				cfg["name"] = pp.Name
			}
			jsonBodyToHCL2Body(ppBody, cfg)
		}

		p.out = append(p.out, transposeTemplatingCalls(postProcessorContent.Bytes())...)
	}
	return nil
}

func (p *PostProcessorParser) Write(out *bytes.Buffer) {
	if len(p.out) > 0 {
		out.Write(p.out)
	}
}

func fixQuoting(old string) string {
	// This regex captures golang template functions that use escaped quotes:
	// {{ env \"myvar\" }}
	// {{ split `some-string` \"-\" 0 }}
	re := regexp.MustCompile(`{{\s*\w*(\s*(\\".*\\")\s*)+\w*\s*}}`)

	body := re.ReplaceAllFunc([]byte(old), func(s []byte) []byte {
		// Get the capture group
		group := re.ReplaceAllString(string(s), `$1`)

		unquoted, err := strconv.Unquote(fmt.Sprintf("\"%s\"", group))
		if err != nil {
			return s
		}
		return []byte(strings.Replace(string(s), group, unquoted, 1))

	})

	return string(body)
}
