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

package validation

import (
	"fmt"
	"log"

	"github.com/hashicorp/hcl/v2"
	"github.com/opentofu/opentofu/internal/configs/configschema"
	"github.com/opentofu/opentofu/internal/tfdiags"
	"github.com/zclconf/go-cty/cty"
)

// WriteOnlyAttributes checks that the write-only attributes are not returned back with an actual value.
// This particular validation does not require to return the diags right away, but we can leave the
// flow move on.
// The diagnostics generated by this validation ensure that the provider works correctly
// and there is no issue in the provider SDK when it comes to the write-only attributes.
// Returning those with actual values can create unknown behavior leading to possible confidential
// information exposure.
// NOTE: Keep this in sync with the equivalent in internal/plugin/validation/write_only.go
func WriteOnlyAttributes(schema *configschema.Block, v cty.Value, resAddr string) (diags tfdiags.Diagnostics) {
	if !schema.ContainsWriteOnly() {
		return diags
	}
	paths := schema.WriteOnlyPaths(v, nil)
	for _, path := range paths {
		pathAsString := tfdiags.FormatCtyPath(path)

		pathVal, err := path.Apply(v)
		if err != nil {
			log.Printf("[WARN] Error when tried to get the path (%s) value from the given object: %s", pathAsString, err)
			continue
		}
		if pathVal.IsNull() {
			continue
		}
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider response",
			Detail:   fmt.Sprintf("Resource type %q returned an actual value for the write-only attribute %q while it is meant to be nil. This is an issue in the provider SDK.", resAddr, pathAsString),
		})
	}
	return diags
}
