package schema

import (
	"context"
	"fmt"
	"reflect"
	"testing"
	"time"

	"github.com/hashicorp/terraform/internal/legacy/terraform"
)

func TestProvisioner_impl(t *testing.T) {
	var _ terraform.ResourceProvisioner = new(Provisioner)
}

func noopApply(ctx context.Context) error {
	return nil
}

func TestProvisionerValidate(t *testing.T) {
	cases := []struct {
		Name   string
		P      *Provisioner
		Config map[string]interface{}
		Err    bool
		Warns  []string
	}{
		{
			Name:   "No ApplyFunc",
			P:      &Provisioner{},
			Config: nil,
			Err:    true,
		},
		{
			Name: "Incorrect schema",
			P: &Provisioner{
				Schema: map[string]*Schema{
					"foo": {},
				},
				ApplyFunc: noopApply,
			},
			Config: nil,
			Err:    true,
		},
		{
			"Basic required field",
			&Provisioner{
				Schema: map[string]*Schema{
					"foo": &Schema{
						Required: true,
						Type:     TypeString,
					},
				},
				ApplyFunc: noopApply,
			},
			nil,
			true,
			nil,
		},

		{
			"Basic required field set",
			&Provisioner{
				Schema: map[string]*Schema{
					"foo": &Schema{
						Required: true,
						Type:     TypeString,
					},
				},
				ApplyFunc: noopApply,
			},
			map[string]interface{}{
				"foo": "bar",
			},
			false,
			nil,
		},
		{
			Name: "Warning from property validation",
			P: &Provisioner{
				Schema: map[string]*Schema{
					"foo": {
						Type:     TypeString,
						Optional: true,
						ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
							ws = append(ws, "Simple warning from property validation")
							return
						},
					},
				},
				ApplyFunc: noopApply,
			},
			Config: map[string]interface{}{
				"foo": "",
			},
			Err:   false,
			Warns: []string{"Simple warning from property validation"},
		},
		{
			Name: "No schema",
			P: &Provisioner{
				Schema:    nil,
				ApplyFunc: noopApply,
			},
			Config: nil,
			Err:    false,
		},
		{
			Name: "Warning from provisioner ValidateFunc",
			P: &Provisioner{
				Schema:    nil,
				ApplyFunc: noopApply,
				ValidateFunc: func(*terraform.ResourceConfig) (ws []string, errors []error) {
					ws = append(ws, "Simple warning from provisioner ValidateFunc")
					return
				},
			},
			Config: nil,
			Err:    false,
			Warns:  []string{"Simple warning from provisioner ValidateFunc"},
		},
	}

	for i, tc := range cases {
		t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) {
			c := terraform.NewResourceConfigRaw(tc.Config)
			ws, es := tc.P.Validate(c)
			if len(es) > 0 != tc.Err {
				t.Fatalf("%d: %#v %s", i, es, es)
			}
			if (tc.Warns != nil || len(ws) != 0) && !reflect.DeepEqual(ws, tc.Warns) {
				t.Fatalf("%d: warnings mismatch, actual: %#v", i, ws)
			}
		})
	}
}

func TestProvisionerApply(t *testing.T) {
	cases := []struct {
		Name   string
		P      *Provisioner
		Conn   map[string]string
		Config map[string]interface{}
		Err    bool
	}{
		{
			"Basic config",
			&Provisioner{
				ConnSchema: map[string]*Schema{
					"foo": &Schema{
						Type:     TypeString,
						Optional: true,
					},
				},

				Schema: map[string]*Schema{
					"foo": &Schema{
						Type:     TypeInt,
						Optional: true,
					},
				},

				ApplyFunc: func(ctx context.Context) error {
					cd := ctx.Value(ProvConnDataKey).(*ResourceData)
					d := ctx.Value(ProvConfigDataKey).(*ResourceData)
					if d.Get("foo").(int) != 42 {
						return fmt.Errorf("bad config data")
					}
					if cd.Get("foo").(string) != "bar" {
						return fmt.Errorf("bad conn data")
					}

					return nil
				},
			},
			map[string]string{
				"foo": "bar",
			},
			map[string]interface{}{
				"foo": 42,
			},
			false,
		},
	}

	for i, tc := range cases {
		t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) {
			c := terraform.NewResourceConfigRaw(tc.Config)

			state := &terraform.InstanceState{
				Ephemeral: terraform.EphemeralState{
					ConnInfo: tc.Conn,
				},
			}

			err := tc.P.Apply(nil, state, c)
			if err != nil != tc.Err {
				t.Fatalf("%d: %s", i, err)
			}
		})
	}
}

func TestProvisionerApply_nilState(t *testing.T) {
	p := &Provisioner{
		ConnSchema: map[string]*Schema{
			"foo": &Schema{
				Type:     TypeString,
				Optional: true,
			},
		},

		Schema: map[string]*Schema{
			"foo": &Schema{
				Type:     TypeInt,
				Optional: true,
			},
		},

		ApplyFunc: func(ctx context.Context) error {
			return nil
		},
	}

	conf := map[string]interface{}{
		"foo": 42,
	}

	c := terraform.NewResourceConfigRaw(conf)
	err := p.Apply(nil, nil, c)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
}

func TestProvisionerStop(t *testing.T) {
	var p Provisioner

	// Verify stopch blocks
	ch := p.StopContext().Done()
	select {
	case <-ch:
		t.Fatal("should not be stopped")
	case <-time.After(10 * time.Millisecond):
	}

	// Stop it
	if err := p.Stop(); err != nil {
		t.Fatalf("err: %s", err)
	}

	select {
	case <-ch:
	case <-time.After(10 * time.Millisecond):
		t.Fatal("should be stopped")
	}
}

func TestProvisionerStop_apply(t *testing.T) {
	p := &Provisioner{
		ConnSchema: map[string]*Schema{
			"foo": &Schema{
				Type:     TypeString,
				Optional: true,
			},
		},

		Schema: map[string]*Schema{
			"foo": &Schema{
				Type:     TypeInt,
				Optional: true,
			},
		},

		ApplyFunc: func(ctx context.Context) error {
			<-ctx.Done()
			return nil
		},
	}

	conn := map[string]string{
		"foo": "bar",
	}

	conf := map[string]interface{}{
		"foo": 42,
	}

	c := terraform.NewResourceConfigRaw(conf)
	state := &terraform.InstanceState{
		Ephemeral: terraform.EphemeralState{
			ConnInfo: conn,
		},
	}

	// Run the apply in a goroutine
	doneCh := make(chan struct{})
	go func() {
		p.Apply(nil, state, c)
		close(doneCh)
	}()

	// Should block
	select {
	case <-doneCh:
		t.Fatal("should not be done")
	case <-time.After(10 * time.Millisecond):
	}

	// Stop!
	p.Stop()

	select {
	case <-doneCh:
	case <-time.After(10 * time.Millisecond):
		t.Fatal("should be done")
	}
}

func TestProvisionerStop_stopFirst(t *testing.T) {
	var p Provisioner

	// Stop it
	if err := p.Stop(); err != nil {
		t.Fatalf("err: %s", err)
	}

	select {
	case <-p.StopContext().Done():
	case <-time.After(10 * time.Millisecond):
		t.Fatal("should be stopped")
	}
}
