// Copyright IBM Corp. 2014, 2026
// SPDX-License-Identifier: BUSL-1.1

package views

import (
	encJson "encoding/json"
	"fmt"
	"sort"

	"github.com/hashicorp/terraform/internal/command/arguments"
	"github.com/hashicorp/terraform/internal/moduleref"
	"github.com/hashicorp/terraform/internal/tfdiags"
	"github.com/xlab/treeprint"
)

type Modules interface {
	// Display renders the list of module entries.
	Display(manifest moduleref.Manifest) int

	// Diagnostics renders early diagnostics, resulting from argument parsing.
	Diagnostics(diags tfdiags.Diagnostics)
}

func NewModules(vt arguments.ViewType, view *View) Modules {
	switch vt {
	case arguments.ViewJSON:
		return &ModulesJSON{view: view}
	case arguments.ViewHuman:
		return &ModulesHuman{view: view}
	default:
		panic(fmt.Sprintf("unknown view type %v", vt))
	}
}

type ModulesHuman struct {
	view *View
}

var _ Modules = (*ModulesHuman)(nil)

func (v *ModulesHuman) Display(manifest moduleref.Manifest) int {
	if len(manifest.Records) == 0 {
		v.view.streams.Println("No modules found in configuration.")
		return 0
	}
	printRoot := treeprint.New()

	// ensure output is deterministic
	sort.Sort(manifest.Records)

	populateTreeNode(printRoot, &moduleref.Record{
		Children: manifest.Records,
	})

	v.view.streams.Println(fmt.Sprintf("\nModules declared by configuration:\n%s", printRoot.String()))
	return 0
}

func populateTreeNode(tree treeprint.Tree, node *moduleref.Record) {
	for _, childNode := range node.Children {
		item := fmt.Sprintf("\"%s\"[%s]", childNode.Key, childNode.Source.String())
		if childNode.Version != nil {
			item += fmt.Sprintf(" %s", childNode.Version)
			// Avoid rendering the version constraint if an exact version is given i.e. 'version = "1.2.3"'
			if childNode.VersionConstraints != nil && childNode.VersionConstraints.String() != childNode.Version.String() {
				item += fmt.Sprintf(" (%s)", childNode.VersionConstraints.String())
			}
		}
		branch := tree.AddBranch(item)
		populateTreeNode(branch, childNode)
	}
}

func (v *ModulesHuman) Diagnostics(diags tfdiags.Diagnostics) {
	v.view.Diagnostics(diags)
}

type ModulesJSON struct {
	view *View
}

var _ Modules = (*ModulesHuman)(nil)

func (v *ModulesJSON) Display(manifest moduleref.Manifest) int {
	var bytes []byte
	var err error

	flattenedManifest := flattenManifest(manifest)
	if bytes, err = encJson.Marshal(flattenedManifest); err != nil {
		v.view.streams.Eprintf("error marshalling manifest: %v", err)
		return 1
	}

	v.view.streams.Println(string(bytes))
	return 0
}

// FlattenManifest returns the nested contents of a moduleref.Manifest in
// a flattened format with the VersionConstraints and Children attributes
// ommited for the purposes of the json format of the modules command
func flattenManifest(m moduleref.Manifest) map[string]interface{} {
	var flatten func(records []*moduleref.Record)
	var recordList []map[string]string
	flatten = func(records []*moduleref.Record) {
		for _, record := range records {
			if record.Version != nil {
				recordList = append(recordList, map[string]string{
					"key":     record.Key,
					"source":  record.Source.String(),
					"version": record.Version.String(),
				})
			} else {
				recordList = append(recordList, map[string]string{
					"key":     record.Key,
					"source":  record.Source.String(),
					"version": "",
				})
			}

			if len(record.Children) > 0 {
				flatten(record.Children)
			}
		}
	}

	flatten(m.Records)
	ret := map[string]interface{}{
		"format_version": m.FormatVersion,
		"modules":        recordList,
	}
	return ret
}

func (v *ModulesJSON) Diagnostics(diags tfdiags.Diagnostics) {
	v.view.Diagnostics(diags)
}
