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

package plugin

import (
	"io"
	"testing"

	"github.com/golang/mock/gomock"
	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
	"github.com/hashicorp/terraform/internal/configs/hcl2shim"
	"github.com/hashicorp/terraform/internal/provisioners"
	proto "github.com/hashicorp/terraform/internal/tfplugin5"
	"github.com/zclconf/go-cty/cty"

	mockproto "github.com/hashicorp/terraform/internal/plugin/mock_proto"
)

var _ provisioners.Interface = (*GRPCProvisioner)(nil)

var (
	equateEmpty   = cmpopts.EquateEmpty()
	typeComparer  = cmp.Comparer(cty.Type.Equals)
	valueComparer = cmp.Comparer(cty.Value.RawEquals)
)

func mockProvisionerClient(t *testing.T) *mockproto.MockProvisionerClient {
	ctrl := gomock.NewController(t)
	client := mockproto.NewMockProvisionerClient(ctrl)

	// we always need a GetSchema method
	client.EXPECT().GetSchema(
		gomock.Any(),
		gomock.Any(),
	).Return(provisionerProtoSchema(), nil)

	return client
}

func provisionerProtoSchema() *proto.GetProvisionerSchema_Response {
	return &proto.GetProvisionerSchema_Response{
		Provisioner: &proto.Schema{
			Block: &proto.Schema_Block{
				Attributes: []*proto.Schema_Attribute{
					{
						Name:     "attr",
						Type:     []byte(`"string"`),
						Required: true,
					},
				},
			},
		},
	}
}

func TestGRPCProvisioner_GetSchema(t *testing.T) {
	p := &GRPCProvisioner{
		client: mockProvisionerClient(t),
	}

	resp := p.GetSchema()
	checkDiags(t, resp.Diagnostics)
}

func TestGRPCProvisioner_ValidateProvisionerConfig(t *testing.T) {
	client := mockProvisionerClient(t)
	p := &GRPCProvisioner{
		client: client,
	}

	client.EXPECT().ValidateProvisionerConfig(
		gomock.Any(),
		gomock.Any(),
	).Return(&proto.ValidateProvisionerConfig_Response{}, nil)

	cfg := hcl2shim.HCL2ValueFromConfigValue(map[string]interface{}{"attr": "value"})
	resp := p.ValidateProvisionerConfig(provisioners.ValidateProvisionerConfigRequest{Config: cfg})
	checkDiags(t, resp.Diagnostics)
}

func TestGRPCProvisioner_ProvisionResource(t *testing.T) {
	ctrl := gomock.NewController(t)
	client := mockproto.NewMockProvisionerClient(ctrl)

	// we always need a GetSchema method
	client.EXPECT().GetSchema(
		gomock.Any(),
		gomock.Any(),
	).Return(provisionerProtoSchema(), nil)

	stream := mockproto.NewMockProvisioner_ProvisionResourceClient(ctrl)
	stream.EXPECT().Recv().Return(&proto.ProvisionResource_Response{
		Output: "provisioned",
	}, io.EOF)

	client.EXPECT().ProvisionResource(
		gomock.Any(),
		gomock.Any(),
	).Return(stream, nil)

	p := &GRPCProvisioner{
		client: client,
	}

	rec := &provisionRecorder{}

	resp := p.ProvisionResource(provisioners.ProvisionResourceRequest{
		Config: cty.ObjectVal(map[string]cty.Value{
			"attr": cty.StringVal("value"),
		}),
		Connection: cty.EmptyObjectVal,
		UIOutput:   rec,
	})

	if resp.Diagnostics.HasErrors() {
		t.Fatal(resp.Diagnostics.Err())
	}

	if len(rec.output) == 0 || rec.output[0] != "provisioned" {
		t.Fatalf("expected %q, got %q", []string{"provisioned"}, rec.output)
	}
}

type provisionRecorder struct {
	output []string
}

func (r *provisionRecorder) Output(s string) {
	r.output = append(r.output, s)
}

func TestGRPCProvisioner_Stop(t *testing.T) {
	ctrl := gomock.NewController(t)
	client := mockproto.NewMockProvisionerClient(ctrl)
	p := &GRPCProvisioner{
		client: client,
	}

	client.EXPECT().Stop(
		gomock.Any(),
		gomock.Any(),
	).Return(&proto.Stop_Response{}, nil)

	err := p.Stop()
	if err != nil {
		t.Fatal(err)
	}
}
