package schema

import (
	"fmt"
	"log"
	"time"

	"github.com/hashicorp/terraform/internal/configs/hcl2shim"
	"github.com/hashicorp/terraform/internal/legacy/terraform"
	"github.com/mitchellh/copystructure"
)

const TimeoutKey = "e2bfb730-ecaa-11e6-8f88-34363bc7c4c0"
const TimeoutsConfigKey = "timeouts"

const (
	TimeoutCreate  = "create"
	TimeoutRead    = "read"
	TimeoutUpdate  = "update"
	TimeoutDelete  = "delete"
	TimeoutDefault = "default"
)

func timeoutKeys() []string {
	return []string{
		TimeoutCreate,
		TimeoutRead,
		TimeoutUpdate,
		TimeoutDelete,
		TimeoutDefault,
	}
}

// could be time.Duration, int64 or float64
func DefaultTimeout(tx interface{}) *time.Duration {
	var td time.Duration
	switch raw := tx.(type) {
	case time.Duration:
		return &raw
	case int64:
		td = time.Duration(raw)
	case float64:
		td = time.Duration(int64(raw))
	default:
		log.Printf("[WARN] Unknown type in DefaultTimeout: %#v", tx)
	}
	return &td
}

type ResourceTimeout struct {
	Create, Read, Update, Delete, Default *time.Duration
}

// ConfigDecode takes a schema and the configuration (available in Diff) and
// validates, parses the timeouts into `t`
func (t *ResourceTimeout) ConfigDecode(s *Resource, c *terraform.ResourceConfig) error {
	if s.Timeouts != nil {
		raw, err := copystructure.Copy(s.Timeouts)
		if err != nil {
			log.Printf("[DEBUG] Error with deep copy: %s", err)
		}
		*t = *raw.(*ResourceTimeout)
	}

	if raw, ok := c.Config[TimeoutsConfigKey]; ok {
		var rawTimeouts []map[string]interface{}
		switch raw := raw.(type) {
		case map[string]interface{}:
			rawTimeouts = append(rawTimeouts, raw)
		case []map[string]interface{}:
			rawTimeouts = raw
		case string:
			if raw == hcl2shim.UnknownVariableValue {
				// Timeout is not defined in the config
				// Defaults will be used instead
				return nil
			} else {
				log.Printf("[ERROR] Invalid timeout value: %q", raw)
				return fmt.Errorf("Invalid Timeout value found")
			}
		case []interface{}:
			for _, r := range raw {
				if rMap, ok := r.(map[string]interface{}); ok {
					rawTimeouts = append(rawTimeouts, rMap)
				} else {
					// Go will not allow a fallthrough
					log.Printf("[ERROR] Invalid timeout structure: %#v", raw)
					return fmt.Errorf("Invalid Timeout structure found")
				}
			}
		default:
			log.Printf("[ERROR] Invalid timeout structure: %#v", raw)
			return fmt.Errorf("Invalid Timeout structure found")
		}

		for _, timeoutValues := range rawTimeouts {
			for timeKey, timeValue := range timeoutValues {
				// validate that we're dealing with the normal CRUD actions
				var found bool
				for _, key := range timeoutKeys() {
					if timeKey == key {
						found = true
						break
					}
				}

				if !found {
					return fmt.Errorf("Unsupported Timeout configuration key found (%s)", timeKey)
				}

				// Get timeout
				rt, err := time.ParseDuration(timeValue.(string))
				if err != nil {
					return fmt.Errorf("Error parsing %q timeout: %s", timeKey, err)
				}

				var timeout *time.Duration
				switch timeKey {
				case TimeoutCreate:
					timeout = t.Create
				case TimeoutUpdate:
					timeout = t.Update
				case TimeoutRead:
					timeout = t.Read
				case TimeoutDelete:
					timeout = t.Delete
				case TimeoutDefault:
					timeout = t.Default
				}

				// If the resource has not delcared this in the definition, then error
				// with an unsupported message
				if timeout == nil {
					return unsupportedTimeoutKeyError(timeKey)
				}

				*timeout = rt
			}
			return nil
		}
	}

	return nil
}

func unsupportedTimeoutKeyError(key string) error {
	return fmt.Errorf("Timeout Key (%s) is not supported", key)
}

// DiffEncode, StateEncode, and MetaDecode are analogous to the Go stdlib JSONEncoder
// interface: they encode/decode a timeouts struct from an instance diff, which is
// where the timeout data is stored after a diff to pass into Apply.
//
// StateEncode encodes the timeout into the ResourceData's InstanceState for
// saving to state
func (t *ResourceTimeout) DiffEncode(id *terraform.InstanceDiff) error {
	return t.metaEncode(id)
}

func (t *ResourceTimeout) StateEncode(is *terraform.InstanceState) error {
	return t.metaEncode(is)
}

// metaEncode encodes the ResourceTimeout into a map[string]interface{} format
// and stores it in the Meta field of the interface it's given.
// Assumes the interface is either *terraform.InstanceState or
// *terraform.InstanceDiff, returns an error otherwise
func (t *ResourceTimeout) metaEncode(ids interface{}) error {
	m := make(map[string]interface{})

	if t.Create != nil {
		m[TimeoutCreate] = t.Create.Nanoseconds()
	}
	if t.Read != nil {
		m[TimeoutRead] = t.Read.Nanoseconds()
	}
	if t.Update != nil {
		m[TimeoutUpdate] = t.Update.Nanoseconds()
	}
	if t.Delete != nil {
		m[TimeoutDelete] = t.Delete.Nanoseconds()
	}
	if t.Default != nil {
		m[TimeoutDefault] = t.Default.Nanoseconds()
		// for any key above that is nil, if default is specified, we need to
		// populate it with the default
		for _, k := range timeoutKeys() {
			if _, ok := m[k]; !ok {
				m[k] = t.Default.Nanoseconds()
			}
		}
	}

	// only add the Timeout to the Meta if we have values
	if len(m) > 0 {
		switch instance := ids.(type) {
		case *terraform.InstanceDiff:
			if instance.Meta == nil {
				instance.Meta = make(map[string]interface{})
			}
			instance.Meta[TimeoutKey] = m
		case *terraform.InstanceState:
			if instance.Meta == nil {
				instance.Meta = make(map[string]interface{})
			}
			instance.Meta[TimeoutKey] = m
		default:
			return fmt.Errorf("Error matching type for Diff Encode")
		}
	}

	return nil
}

func (t *ResourceTimeout) StateDecode(id *terraform.InstanceState) error {
	return t.metaDecode(id)
}
func (t *ResourceTimeout) DiffDecode(is *terraform.InstanceDiff) error {
	return t.metaDecode(is)
}

func (t *ResourceTimeout) metaDecode(ids interface{}) error {
	var rawMeta interface{}
	var ok bool
	switch rawInstance := ids.(type) {
	case *terraform.InstanceDiff:
		rawMeta, ok = rawInstance.Meta[TimeoutKey]
		if !ok {
			return nil
		}
	case *terraform.InstanceState:
		rawMeta, ok = rawInstance.Meta[TimeoutKey]
		if !ok {
			return nil
		}
	default:
		return fmt.Errorf("Unknown or unsupported type in metaDecode: %#v", ids)
	}

	times := rawMeta.(map[string]interface{})
	if len(times) == 0 {
		return nil
	}

	if v, ok := times[TimeoutCreate]; ok {
		t.Create = DefaultTimeout(v)
	}
	if v, ok := times[TimeoutRead]; ok {
		t.Read = DefaultTimeout(v)
	}
	if v, ok := times[TimeoutUpdate]; ok {
		t.Update = DefaultTimeout(v)
	}
	if v, ok := times[TimeoutDelete]; ok {
		t.Delete = DefaultTimeout(v)
	}
	if v, ok := times[TimeoutDefault]; ok {
		t.Default = DefaultTimeout(v)
	}

	return nil
}
