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

package command

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/hashicorp/packer-plugin-sdk/template"
	"github.com/hashicorp/packer/fix"

	"github.com/posener/complete"
)

type FixCommand struct {
	Meta
}

func (c *FixCommand) 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 *FixCommand) ParseArgs(args []string) (*FixArgs, int) {
	var cfg FixArgs
	flags := c.Meta.FlagSet("fix", 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]
	return &cfg, 0
}

func (c *FixCommand) RunContext(ctx context.Context, cla *FixArgs) int {
	if hcl2, _ := isHCLLoaded(cla.Path); hcl2 {
		c.Ui.Error("packer fix only works with JSON files for now.")
		return 1
	}
	// Read the file for decoding
	tplF, err := os.Open(cla.Path)
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error opening template: %s", err))
		return 1
	}
	defer tplF.Close()

	// Decode the JSON into a generic map structure
	var templateData map[string]interface{}
	decoder := json.NewDecoder(tplF)
	if err := decoder.Decode(&templateData); err != nil {
		c.Ui.Error(fmt.Sprintf("Error parsing template: %s", err))
		return 1
	}

	// Close the file since we're done with that
	tplF.Close()

	input := templateData
	for _, name := range fix.FixerOrder {
		var err error
		fixer, ok := fix.Fixers[name]
		if !ok {
			panic("fixer not found: " + name)
		}

		log.Printf("Running fixer: %s", name)
		input, err = fixer.Fix(input)
		if err != nil {
			c.Ui.Error(fmt.Sprintf("Error fixing: %s", err))
			return 1
		}
	}

	var output bytes.Buffer
	encoder := json.NewEncoder(&output)
	if err := encoder.Encode(input); err != nil {
		c.Ui.Error(fmt.Sprintf("Error encoding: %s", err))
		return 1
	}

	var indented bytes.Buffer
	if err := json.Indent(&indented, output.Bytes(), "", "  "); err != nil {
		c.Ui.Error(fmt.Sprintf("Error encoding: %s", err))
		return 1
	}

	result := indented.String()
	result = strings.Replace(result, `\u003c`, "<", -1)
	result = strings.Replace(result, `\u003e`, ">", -1)
	c.Ui.Say(result)

	if cla.Validate == false {
		return 0
	}

	// Attempt to parse and validate the template
	tpl, err := template.Parse(strings.NewReader(result))
	if err != nil {
		c.Ui.Error(fmt.Sprintf(
			"Error! Fixed template fails to parse: %s\n\n"+
				"This is usually caused by an error in the input template.\n"+
				"Please fix the error and try again.",
			err))
		return 1
	}
	if err := tpl.Validate(); err != nil {
		c.Ui.Error(fmt.Sprintf(
			"Error! Fixed template failed to validate: %s\n\n"+
				"This is usually caused by an error in the input template.\n"+
				"Please fix the error and try again.",
			err))
		return 1
	}

	return 0
}

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

  Reads the JSON template and attempts to fix known backwards
  incompatibilities. The fixed template will be outputted to standard out.

  If the template cannot be fixed due to an error, the command will exit
  with a non-zero exit status. Error messages will appear on standard error.

Fixes that are run (in order):

`

	for _, name := range fix.FixerOrder {
		helpText += fmt.Sprintf(
			"  %-27s%s\n", name, fix.Fixers[name].Synopsis())
	}

	helpText += `
Options:

  -validate=true      If true (default), validates the fixed template.
`

	return strings.TrimSpace(helpText)
}

func (c *FixCommand) Synopsis() string {
	return "fixes templates from old versions of packer"
}

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

func (c *FixCommand) AutocompleteFlags() complete.Flags {
	return complete.Flags{
		"-validate": complete.PredictNothing,
	}
}
