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
	}
}
