// expandHealthCheckConfig expands the Check block.
func expandHealthCheckConfig(data interface{}) (*spotinst.HealthCheckConfig, error) {
	if list := data.(*schema.Set).List(); len(list) != 1 {
		return nil, fmt.Errorf("Only a single check block is expected")
	} else {
		m := list[0].(map[string]interface{})
		check := &spotinst.HealthCheckConfig{}

		if v, ok := m["protocol"].(string); ok && v != "" {
			check.Protocol = spotinst.String(v)
		}

		if v, ok := m["endpoint"].(string); ok && v != "" {
			check.Endpoint = spotinst.String(v)
		}

		if v, ok := m["port"].(int); ok && v >= 0 {
			check.Port = spotinst.Int(v)
		}

		if v, ok := m["interval"].(int); ok && v >= 0 {
			check.Interval = spotinst.Int(v)
		}

		if v, ok := m["timeout"].(int); ok && v >= 0 {
			check.Timeout = spotinst.Int(v)
		}

		log.Printf("[DEBUG] HealthCheck check configuration: %#v\n", check)
		return check, nil
	}
}
// buildHealthCheckOpts builds the Spotinst HealthCheck options.
func buildHealthCheckOpts(d *schema.ResourceData, meta interface{}) (*spotinst.HealthCheck, error) {
	healthCheck := &spotinst.HealthCheck{
		Name:       spotinst.String(d.Get("name").(string)),
		ResourceID: spotinst.String(d.Get("resource_id").(string)),
	}

	if v, ok := d.GetOk("check"); ok {
		if check, err := expandHealthCheckConfig(v); err != nil {
			return nil, err
		} else {
			healthCheck.Check = check
		}
	}

	if v, ok := d.GetOk("threshold"); ok {
		if threshold, err := expandHealthCheckThreshold(v); err != nil {
			return nil, err
		} else {
			healthCheck.Check.HealthCheckThreshold = threshold
		}
	}

	if v, ok := d.GetOk("proxy"); ok {
		if proxy, err := expandHealthCheckProxy(v); err != nil {
			return nil, err
		} else {
			healthCheck.HealthCheckProxy = proxy
		}
	}

	return healthCheck, nil
}
func resourceSpotinstHealthCheckUpdate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*spotinst.Client)
	healthCheck := &spotinst.HealthCheck{ID: spotinst.String(d.Id())}
	hasChange := false

	if d.HasChange("name") {
		healthCheck.Name = spotinst.String(d.Get("name").(string))
		hasChange = true
	}

	if d.HasChange("resource_id") {
		healthCheck.ResourceID = spotinst.String(d.Get("resource_id").(string))
		hasChange = true
	}

	if d.HasChange("check") {
		if v, ok := d.GetOk("check"); ok {
			if check, err := expandHealthCheckConfig(v); err != nil {
				return err
			} else {
				healthCheck.Check = check
				hasChange = true
			}
		}
	}

	if d.HasChange("threshold") {
		if v, ok := d.GetOk("threshold"); ok {
			if threshold, err := expandHealthCheckThreshold(v); err != nil {
				return err
			} else {
				healthCheck.Check.HealthCheckThreshold = threshold
				hasChange = true
			}
		}
	}

	if d.HasChange("proxy") {
		if v, ok := d.GetOk("proxy"); ok {
			if proxy, err := expandHealthCheckProxy(v); err != nil {
				return err
			} else {
				healthCheck.HealthCheckProxy = proxy
				hasChange = true
			}
		}
	}

	if hasChange {
		log.Printf("[DEBUG] HealthCheck update configuration: %#v\n", healthCheck)
		_, _, err := client.HealthCheck.Update(healthCheck)
		if err != nil {
			return fmt.Errorf("[ERROR] Error updating health check: %s", err)
		}
	}

	return resourceSpotinstHealthCheckRead(d, meta)
}
// buildSubscriptionOpts builds the Spotinst Subscription options.
func buildSubscriptionOpts(d *schema.ResourceData, meta interface{}) (*spotinst.Subscription, error) {
	subscription := &spotinst.Subscription{
		ResourceID: spotinst.String(d.Get("resource_id").(string)),
		EventType:  spotinst.String(strings.ToUpper(d.Get("event_type").(string))),
		Protocol:   spotinst.String(d.Get("protocol").(string)),
		Endpoint:   spotinst.String(d.Get("endpoint").(string)),
		Format:     d.Get("format").(map[string]interface{}),
	}

	return subscription, nil
}
func resourceSpotinstHealthCheckDelete(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*spotinst.Client)
	log.Printf("[INFO] Deleting health check: %s\n", d.Id())
	healthCheck := &spotinst.HealthCheck{ID: spotinst.String(d.Id())}
	_, err := client.HealthCheck.Delete(healthCheck)
	if err != nil {
		return fmt.Errorf("[ERROR] Error deleting health check: %s", err)
	}
	return nil
}
func resourceSpotinstSubscriptionUpdate(d *schema.ResourceData, meta interface{}) error {
	hasChange := false
	client := meta.(*spotinst.Client)
	update := &spotinst.Subscription{ID: spotinst.String(d.Id())}

	if d.HasChange("resource_id") {
		update.ResourceID = spotinst.String(d.Get("resource_id").(string))
		hasChange = true
	}

	if d.HasChange("event_type") {
		update.EventType = spotinst.String(d.Get("event_type").(string))
		hasChange = true
	}

	if d.HasChange("protocol") {
		update.Protocol = spotinst.String(d.Get("protocol").(string))
		hasChange = true
	}

	if d.HasChange("endpoint") {
		update.Endpoint = spotinst.String(d.Get("endpoint").(string))
		hasChange = true
	}

	if d.HasChange("format") {
		update.Format = d.Get("format").(map[string]interface{})
		hasChange = true
	}

	if hasChange {
		log.Printf("[DEBUG] Subscription update configuration: %#v\n", update)
		_, _, err := client.Subscription.Update(update)
		if err != nil {
			return fmt.Errorf("[ERROR] Error updating subscription: %s", err)
		}
	}

	return resourceSpotinstSubscriptionRead(d, meta)
}
// expandHealthCheckProxy expands the Proxy block.
func expandHealthCheckProxy(data interface{}) (*spotinst.HealthCheckProxy, error) {
	if list := data.(*schema.Set).List(); len(list) != 1 {
		return nil, fmt.Errorf("Only a single proxy block is expected")
	} else {
		m := list[0].(map[string]interface{})
		proxy := &spotinst.HealthCheckProxy{}

		if v, ok := m["addr"].(string); ok && v != "" {
			proxy.Addr = spotinst.String(v)
		}

		if v, ok := m["port"].(int); ok && v > 0 {
			proxy.Port = spotinst.Int(v)
		}

		log.Printf("[DEBUG] HealthCheck proxy configuration: %#v\n", proxy)
		return proxy, nil
	}
}