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

package statefile

import (
	"encoding/json"
	"fmt"
	"strconv"
	"strings"

	"github.com/hashicorp/hcl/v2/hclsyntax"
	"github.com/zclconf/go-cty/cty"
	ctyjson "github.com/zclconf/go-cty/cty/json"

	"github.com/hashicorp/terraform/internal/addrs"
	"github.com/hashicorp/terraform/internal/configs"
	"github.com/hashicorp/terraform/internal/states"
	"github.com/hashicorp/terraform/internal/tfdiags"
)

func upgradeStateV3ToV4(old *stateV3) (*stateV4, error) {

	if old.Serial < 0 {
		// The new format is using uint64 here, which should be fine for any
		// real state (we only used positive integers in practice) but we'll
		// catch this explicitly here to avoid weird behavior if a state file
		// has been tampered with in some way.
		return nil, fmt.Errorf("state has serial less than zero, which is invalid")
	}

	new := &stateV4{
		TerraformVersion: old.TFVersion,
		Serial:           uint64(old.Serial),
		Lineage:          old.Lineage,
		RootOutputs:      map[string]outputStateV4{},
		Resources:        []resourceStateV4{},
	}

	if new.TerraformVersion == "" {
		// Older formats considered this to be optional, but now it's required
		// and so we'll stub it out with something that's definitely older
		// than the version that really created this state.
		new.TerraformVersion = "0.0.0"
	}

	for _, msOld := range old.Modules {
		if len(msOld.Path) < 1 || msOld.Path[0] != "root" {
			return nil, fmt.Errorf("state contains invalid module path %#v", msOld.Path)
		}

		// Convert legacy-style module address into our newer address type.
		// Since these old formats are only generated by versions of Terraform
		// that don't support count and for_each on modules, we can just assume
		// all of the modules are unkeyed.
		moduleAddr := make(addrs.ModuleInstance, len(msOld.Path)-1)
		for i, name := range msOld.Path[1:] {
			if !hclsyntax.ValidIdentifier(name) {
				// If we don't fail here then we'll produce an invalid state
				// version 4 which subsequent operations will reject, so we'll
				// fail early here for safety to make sure we can never
				// inadvertently commit an invalid snapshot to a backend.
				return nil, fmt.Errorf("state contains invalid module path %#v: %q is not a valid identifier; rename it in Terraform 0.11 before upgrading to Terraform 0.12", msOld.Path, name)
			}
			moduleAddr[i] = addrs.ModuleInstanceStep{
				Name:        name,
				InstanceKey: addrs.NoKey,
			}
		}

		// In a v3 state file, a "resource state" is actually an instance
		// state, so we need to fill in a missing level of hierarchy here
		// by lazily creating resource states as we encounter them.
		// We'll track them in here, keyed on the string representation of
		// the resource address.
		resourceStates := map[string]*resourceStateV4{}

		for legacyAddr, rsOld := range msOld.Resources {
			instAddr, err := parseLegacyResourceAddress(legacyAddr)
			if err != nil {
				return nil, err
			}

			resAddr := instAddr.Resource
			rs, exists := resourceStates[resAddr.String()]
			if !exists {
				var modeStr string
				switch resAddr.Mode {
				case addrs.ManagedResourceMode:
					modeStr = "managed"
				case addrs.DataResourceMode:
					modeStr = "data"
				default:
					return nil, fmt.Errorf("state contains resource %s with an unsupported resource mode %#v", resAddr, resAddr.Mode)
				}

				// In state versions prior to 4 we allowed each instance of a
				// resource to have its own provider configuration address,
				// which makes no real sense in practice because providers
				// are associated with resources in the configuration. We
				// elevate that to the resource level during this upgrade,
				// implicitly taking the provider address of the first instance
				// we encounter for each resource. While this is lossy in
				// theory, in practice there is no reason for these values to
				// differ between instances.
				var providerAddr addrs.AbsProviderConfig
				oldProviderAddr := rsOld.Provider
				if strings.Contains(oldProviderAddr, "provider.") {
					// Smells like a new-style provider address, but we'll test it.
					var diags tfdiags.Diagnostics
					providerAddr, diags = addrs.ParseLegacyAbsProviderConfigStr(oldProviderAddr)
					if diags.HasErrors() {
						if strings.Contains(oldProviderAddr, "${") {
							// There seems to be a common misconception that
							// interpolation was valid in provider aliases
							// in 0.11, so we'll use a specialized error
							// message for that case.
							return nil, fmt.Errorf("invalid provider config reference %q for %s: this alias seems to contain a template interpolation sequence, which was not supported but also not error-checked in Terraform 0.11. To proceed, rename the associated provider alias to a valid identifier and apply the change with Terraform 0.11 before upgrading to Terraform 0.12", oldProviderAddr, instAddr)
						}
						return nil, fmt.Errorf("invalid provider config reference %q for %s: %s", oldProviderAddr, instAddr, diags.Err())
					}
				} else {
					// Smells like an old-style module-local provider address,
					// which we'll need to migrate. We'll assume it's referring
					// to the same module the resource is in, which might be
					// incorrect but it'll get fixed up next time any updates
					// are made to an instance.
					if oldProviderAddr != "" {
						localAddr, diags := configs.ParseProviderConfigCompactStr(oldProviderAddr)
						if diags.HasErrors() {
							if strings.Contains(oldProviderAddr, "${") {
								// There seems to be a common misconception that
								// interpolation was valid in provider aliases
								// in 0.11, so we'll use a specialized error
								// message for that case.
								return nil, fmt.Errorf("invalid legacy provider config reference %q for %s: this alias seems to contain a template interpolation sequence, which was not supported but also not error-checked in Terraform 0.11. To proceed, rename the associated provider alias to a valid identifier and apply the change with Terraform 0.11 before upgrading to Terraform 0.12", oldProviderAddr, instAddr)
							}
							return nil, fmt.Errorf("invalid legacy provider config reference %q for %s: %s", oldProviderAddr, instAddr, diags.Err())
						}
						providerAddr = addrs.AbsProviderConfig{
							Module: moduleAddr.Module(),
							// We use NewLegacyProvider here so we can use
							// LegacyString() below to get the appropriate
							// legacy-style provider string.
							Provider: addrs.NewLegacyProvider(localAddr.LocalName),
							Alias:    localAddr.Alias,
						}
					} else {
						providerAddr = addrs.AbsProviderConfig{
							Module: moduleAddr.Module(),
							// We use NewLegacyProvider here so we can use
							// LegacyString() below to get the appropriate
							// legacy-style provider string.
							Provider: addrs.NewLegacyProvider(resAddr.ImpliedProvider()),
						}
					}
				}

				rs = &resourceStateV4{
					Module:         moduleAddr.String(),
					Mode:           modeStr,
					Type:           resAddr.Type,
					Name:           resAddr.Name,
					Instances:      []instanceObjectStateV4{},
					ProviderConfig: providerAddr.LegacyString(),
				}
				resourceStates[resAddr.String()] = rs
			}

			// Now we'll deal with the instance itself, which may either be
			// the first instance in a resource we just created or an additional
			// instance for a resource added on a prior loop.
			instKey := instAddr.Key
			if isOld := rsOld.Primary; isOld != nil {
				isNew, err := upgradeInstanceObjectV3ToV4(rsOld, isOld, instKey, states.NotDeposed)
				if err != nil {
					return nil, fmt.Errorf("failed to migrate primary generation of %s: %s", instAddr, err)
				}
				rs.Instances = append(rs.Instances, *isNew)
			}
			for i, isOld := range rsOld.Deposed {
				// When we migrate old instances we'll use sequential deposed
				// keys just so that the upgrade result is deterministic. New
				// deposed keys allocated moving forward will be pseudorandomly
				// selected, but we check for collisions and so these
				// non-random ones won't hurt.
				deposedKey := states.DeposedKey(fmt.Sprintf("%08x", i+1))
				isNew, err := upgradeInstanceObjectV3ToV4(rsOld, isOld, instKey, deposedKey)
				if err != nil {
					return nil, fmt.Errorf("failed to migrate deposed generation index %d of %s: %s", i, instAddr, err)
				}
				rs.Instances = append(rs.Instances, *isNew)
			}

			if instKey != addrs.NoKey && rs.EachMode == "" {
				rs.EachMode = "list"
			}
		}

		for _, rs := range resourceStates {
			new.Resources = append(new.Resources, *rs)
		}

		if len(msOld.Path) == 1 && msOld.Path[0] == "root" {
			// We'll migrate the outputs for this module too, then.
			for name, oldOS := range msOld.Outputs {
				newOS := outputStateV4{
					Sensitive: oldOS.Sensitive,
				}

				valRaw := oldOS.Value
				valSrc, err := json.Marshal(valRaw)
				if err != nil {
					// Should never happen, because this value came from JSON
					// in the first place and so we're just round-tripping here.
					return nil, fmt.Errorf("failed to serialize output %q value as JSON: %s", name, err)
				}

				// The "type" field in state V2 wasn't really that useful
				// since it was only able to capture string vs. list vs. map.
				// For this reason, during upgrade we'll just discard it
				// altogether and use cty's idea of the implied type of
				// turning our old value into JSON.
				ty, err := ctyjson.ImpliedType(valSrc)
				if err != nil {
					// REALLY should never happen, because we literally just
					// encoded this as JSON above!
					return nil, fmt.Errorf("failed to parse output %q value from JSON: %s", name, err)
				}

				// ImpliedType tends to produce structural types, but since older
				// version of Terraform didn't support those a collection type
				// is probably what was intended, so we'll see if we can
				// interpret our value as one.
				ty = simplifyImpliedValueType(ty)

				tySrc, err := ctyjson.MarshalType(ty)
				if err != nil {
					return nil, fmt.Errorf("failed to serialize output %q type as JSON: %s", name, err)
				}

				newOS.ValueRaw = json.RawMessage(valSrc)
				newOS.ValueTypeRaw = json.RawMessage(tySrc)

				new.RootOutputs[name] = newOS
			}
		}
	}

	new.normalize()

	return new, nil
}

func upgradeInstanceObjectV3ToV4(rsOld *resourceStateV2, isOld *instanceStateV2, instKey addrs.InstanceKey, deposedKey states.DeposedKey) (*instanceObjectStateV4, error) {

	// Schema versions were, in prior formats, a private concern of the provider
	// SDK, and not a first-class concept in the state format. Here we're
	// sniffing for the pre-0.12 SDK's way of representing schema versions
	// and promoting it to our first-class field if we find it. We'll ignore
	// it if it doesn't look like what the SDK would've written. If this
	// sniffing fails then we'll assume schema version 0.
	var schemaVersion uint64
	migratedSchemaVersion := false
	if raw, exists := isOld.Meta["schema_version"]; exists {
		switch tv := raw.(type) {
		case string:
			v, err := strconv.ParseUint(tv, 10, 64)
			if err == nil {
				schemaVersion = v
				migratedSchemaVersion = true
			}
		case int:
			schemaVersion = uint64(tv)
			migratedSchemaVersion = true
		case float64:
			schemaVersion = uint64(tv)
			migratedSchemaVersion = true
		}
	}

	private := map[string]interface{}{}
	for k, v := range isOld.Meta {
		if k == "schema_version" && migratedSchemaVersion {
			// We're gonna promote this into our first-class schema version field
			continue
		}
		private[k] = v
	}
	var privateJSON []byte
	if len(private) != 0 {
		var err error
		privateJSON, err = json.Marshal(private)
		if err != nil {
			// This shouldn't happen, because the Meta values all came from JSON
			// originally anyway.
			return nil, fmt.Errorf("cannot serialize private instance object data: %s", err)
		}
	}

	var status string
	if isOld.Tainted {
		status = "tainted"
	}

	var instKeyRaw interface{}
	switch tk := instKey.(type) {
	case addrs.IntKey:
		instKeyRaw = int(tk)
	case addrs.StringKey:
		instKeyRaw = string(tk)
	default:
		if instKeyRaw != nil {
			return nil, fmt.Errorf("unsupported instance key: %#v", instKey)
		}
	}

	var attributes map[string]string
	if isOld.Attributes != nil {
		attributes = make(map[string]string, len(isOld.Attributes))
		for k, v := range isOld.Attributes {
			attributes[k] = v
		}
	}
	if isOld.ID != "" {
		// As a special case, if we don't already have an "id" attribute and
		// yet there's a non-empty first-class ID on the old object then we'll
		// create a synthetic id attribute to avoid losing that first-class id.
		// In practice this generally arises only in tests where state literals
		// are hand-written in a non-standard way; real code prior to 0.12
		// would always force the first-class ID to be copied into the
		// id attribute before storing.
		if attributes == nil {
			attributes = make(map[string]string, len(isOld.Attributes))
		}
		if idVal := attributes["id"]; idVal == "" {
			attributes["id"] = isOld.ID
		}
	}

	return &instanceObjectStateV4{
		IndexKey:       instKeyRaw,
		Status:         status,
		Deposed:        string(deposedKey),
		AttributesFlat: attributes,
		SchemaVersion:  schemaVersion,
		PrivateRaw:     privateJSON,
	}, nil
}

// parseLegacyResourceAddress parses the different identifier format used
// state formats before version 4, like "instance.name.0".
func parseLegacyResourceAddress(s string) (addrs.ResourceInstance, error) {
	var ret addrs.ResourceInstance

	// Split based on ".". Every resource address should have at least two
	// elements (type and name).
	parts := strings.Split(s, ".")
	if len(parts) < 2 || len(parts) > 4 {
		return ret, fmt.Errorf("invalid internal resource address format: %s", s)
	}

	// Data resource if we have at least 3 parts and the first one is data
	ret.Resource.Mode = addrs.ManagedResourceMode
	if len(parts) > 2 && parts[0] == "data" {
		ret.Resource.Mode = addrs.DataResourceMode
		parts = parts[1:]
	}

	// If we're not a data resource and we have more than 3, then it is an error
	if len(parts) > 3 && ret.Resource.Mode != addrs.DataResourceMode {
		return ret, fmt.Errorf("invalid internal resource address format: %s", s)
	}

	// Build the parts of the resource address that are guaranteed to exist
	ret.Resource.Type = parts[0]
	ret.Resource.Name = parts[1]
	ret.Key = addrs.NoKey

	// If we have more parts, then we have an index. Parse that.
	if len(parts) > 2 {
		idx, err := strconv.ParseInt(parts[2], 0, 0)
		if err != nil {
			return ret, fmt.Errorf("error parsing resource address %q: %s", s, err)
		}

		ret.Key = addrs.IntKey(idx)
	}

	return ret, nil
}

// simplifyImpliedValueType attempts to heuristically simplify a value type
// derived from a legacy stored output value into something simpler that
// is closer to what would've fitted into the pre-v0.12 value type system.
func simplifyImpliedValueType(ty cty.Type) cty.Type {
	switch {
	case ty.IsTupleType():
		// If all of the element types are the same then we'll make this
		// a list instead. This is very likely to be true, since prior versions
		// of Terraform did not officially support mixed-type collections.

		if ty.Equals(cty.EmptyTuple) {
			// Don't know what the element type would be, then.
			return ty
		}

		etys := ty.TupleElementTypes()
		ety := etys[0]
		for _, other := range etys[1:] {
			if !other.Equals(ety) {
				// inconsistent types
				return ty
			}
		}
		ety = simplifyImpliedValueType(ety)
		return cty.List(ety)

	case ty.IsObjectType():
		// If all of the attribute types are the same then we'll make this
		// a map instead. This is very likely to be true, since prior versions
		// of Terraform did not officially support mixed-type collections.

		if ty.Equals(cty.EmptyObject) {
			// Don't know what the element type would be, then.
			return ty
		}

		atys := ty.AttributeTypes()
		var ety cty.Type
		for _, other := range atys {
			if ety == cty.NilType {
				ety = other
				continue
			}
			if !other.Equals(ety) {
				// inconsistent types
				return ty
			}
		}
		ety = simplifyImpliedValueType(ety)
		return cty.Map(ety)

	default:
		// No other normalizations are possible
		return ty
	}
}
