// Copyright IBM Corp. 2016, 2025
// SPDX-License-Identifier: MPL-2.0

package api

import (
	"fmt"
	"os"
	"strconv"
	"strings"

	"github.com/hashicorp/hcl"
	"github.com/hashicorp/hcl/hcl/ast"
	hclParser "github.com/hashicorp/hcl/hcl/parser"
)

// allowHclDuplicatesEnvVar is an environment variable that allows Vault to revert back to accepting HCL files with
// duplicate attributes. It's temporary until we finish the deprecation process, at which point this will be removed
const allowHclDuplicatesEnvVar = "VAULT_ALLOW_PENDING_REMOVAL_DUPLICATE_HCL_ATTRIBUTES"

// parseAndCheckForDuplicateHclAttributes parses the input JSON/HCL file and if it is HCL it also checks
// for duplicate keys in the HCL file, allowing callers to handle the issue accordingly. It now only accepts duplicate
// keys if the environment variable VAULT_ALLOW_PENDING_REMOVAL_DUPLICATE_HCL_ATTRIBUTES is set to true. In a future
// release we'll remove this function entirely and there will be no way to parse HCL files with duplicate keys.
// TODO (HCL_DUP_KEYS_DEPRECATION): remove once not used anymore
func parseAndCheckForDuplicateHclAttributes(input string) (res *ast.File, duplicate bool, err error) {
	res, err = hcl.Parse(input)
	if err != nil && strings.Contains(err.Error(), "Each argument can only be defined once") {
		allowHclDuplicatesRaw := os.Getenv(allowHclDuplicatesEnvVar)
		if allowHclDuplicatesRaw == "" {
			// default is to not allow duplicates
			return nil, false, err
		}
		allowHclDuplicates, envParseErr := strconv.ParseBool(allowHclDuplicatesRaw)
		if envParseErr != nil {
			return nil, false, fmt.Errorf("error parsing %q environment variable: %w", allowHclDuplicatesEnvVar, err)
		}
		if !allowHclDuplicates {
			return nil, false, err
		}

		// if allowed by the environment variable, parse again without failing on duplicate attributes
		duplicate = true
		res, err = hclParser.ParseDontErrorOnDuplicateKeys([]byte(input))
	}
	return res, duplicate, err
}
