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

package grpcwrap

import (
	"context"
	"log"
	"strings"
	"unicode/utf8"

	"github.com/hashicorp/terraform/internal/communicator/shared"
	"github.com/hashicorp/terraform/internal/configs/configschema"
	"github.com/hashicorp/terraform/internal/plugin/convert"
	"github.com/hashicorp/terraform/internal/provisioners"
	"github.com/hashicorp/terraform/internal/tfplugin5"
)

// New wraps a provisioners.Interface to implement a grpc ProviderServer.
// This is useful for creating a test binary out of an internal provider
// implementation.
func Provisioner(p provisioners.Interface) tfplugin5.ProvisionerServer {
	return &provisioner{
		provisioner: p,
		schema:      p.GetSchema().Provisioner,
	}
}

type provisioner struct {
	provisioner provisioners.Interface
	schema      *configschema.Block
}

func (p *provisioner) GetSchema(_ context.Context, req *tfplugin5.GetProvisionerSchema_Request) (*tfplugin5.GetProvisionerSchema_Response, error) {
	resp := &tfplugin5.GetProvisionerSchema_Response{}

	resp.Provisioner = &tfplugin5.Schema{
		Block: &tfplugin5.Schema_Block{},
	}

	if p.schema != nil {
		resp.Provisioner.Block = convert.ConfigSchemaToProto(p.schema)
	}

	return resp, nil
}

func (p *provisioner) ValidateProvisionerConfig(_ context.Context, req *tfplugin5.ValidateProvisionerConfig_Request) (*tfplugin5.ValidateProvisionerConfig_Response, error) {
	resp := &tfplugin5.ValidateProvisionerConfig_Response{}
	ty := p.schema.ImpliedType()

	configVal, err := decodeDynamicValue(req.Config, ty)
	if err != nil {
		resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
		return resp, nil
	}

	validateResp := p.provisioner.ValidateProvisionerConfig(provisioners.ValidateProvisionerConfigRequest{
		Config: configVal,
	})

	resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, validateResp.Diagnostics)
	return resp, nil
}

func (p *provisioner) ProvisionResource(req *tfplugin5.ProvisionResource_Request, srv tfplugin5.Provisioner_ProvisionResourceServer) error {
	// We send back a diagnostics over the stream if there was a
	// provisioner-side problem.
	srvResp := &tfplugin5.ProvisionResource_Response{}

	ty := p.schema.ImpliedType()
	configVal, err := decodeDynamicValue(req.Config, ty)
	if err != nil {
		srvResp.Diagnostics = convert.AppendProtoDiag(srvResp.Diagnostics, err)
		srv.Send(srvResp)
		return nil
	}

	connVal, err := decodeDynamicValue(req.Connection, shared.ConnectionBlockSupersetSchema.ImpliedType())
	if err != nil {
		srvResp.Diagnostics = convert.AppendProtoDiag(srvResp.Diagnostics, err)
		srv.Send(srvResp)
		return nil
	}

	resp := p.provisioner.ProvisionResource(provisioners.ProvisionResourceRequest{
		Config:     configVal,
		Connection: connVal,
		UIOutput:   uiOutput{srv},
	})

	srvResp.Diagnostics = convert.AppendProtoDiag(srvResp.Diagnostics, resp.Diagnostics)
	srv.Send(srvResp)
	return nil
}

func (p *provisioner) Stop(context.Context, *tfplugin5.Stop_Request) (*tfplugin5.Stop_Response, error) {
	resp := &tfplugin5.Stop_Response{}
	err := p.provisioner.Stop()
	if err != nil {
		resp.Error = err.Error()
	}
	return resp, nil
}

// uiOutput implements the terraform.UIOutput interface to adapt the grpc
// stream to the legacy Provisioner.Apply method.
type uiOutput struct {
	srv tfplugin5.Provisioner_ProvisionResourceServer
}

func (o uiOutput) Output(s string) {
	err := o.srv.Send(&tfplugin5.ProvisionResource_Response{
		Output: strings.ToValidUTF8(s, string(utf8.RuneError)),
	})
	if err != nil {
		log.Printf("[ERROR] %s", err)
	}
}
