// Code generated by protoc-gen-go_temporal. DO NOT EDIT.
// versions:
//
//	protoc-gen-go_temporal dev (latest)
//	protoc (unknown)
//
// source: test/issue-125/v1/issue-125.proto
package issue_125v1

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	expression "github.com/cludden/protoc-gen-go-temporal/pkg/expression"
	helpers "github.com/cludden/protoc-gen-go-temporal/pkg/helpers"
	scheme "github.com/cludden/protoc-gen-go-temporal/pkg/scheme"
	testutil "github.com/cludden/protoc-gen-go-temporal/pkg/testutil"
	uuid "github.com/google/uuid"
	gohomedir "github.com/mitchellh/go-homedir"
	v2 "github.com/urfave/cli/v2"
	enumsv1 "go.temporal.io/api/enums/v1"
	serviceerror "go.temporal.io/api/serviceerror"
	client "go.temporal.io/sdk/client"
	converter "go.temporal.io/sdk/converter"
	temporal "go.temporal.io/sdk/temporal"
	testsuite "go.temporal.io/sdk/testsuite"
	worker "go.temporal.io/sdk/worker"
	workflow "go.temporal.io/sdk/workflow"
	protojson "google.golang.org/protobuf/encoding/protojson"
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	"log/slog"
	"os"
	"sort"
	"strings"
	"sync"
	"sync/atomic"
	"time"
)

// Issue125ServiceTaskQueue is the default task-queue for a issue_125.v1.Issue125Service worker
var Issue125ServiceTaskQueue = "issue-125-v1"

// issue_125.v1.Issue125Service workflow names
const (
	FooWorkflowName = "issue_125.v1.Issue125Service.Foo"
)

// issue_125.v1.Issue125Service workflow id expressions
var (
	FooIdexpression = expression.MustParseExpression("foo/${! id }")
)

// issue_125.v1.Issue125Service update names
const (
	BarUpdateName = "issue_125.v1.Issue125Service.Bar"
	BazUpdateName = "issue_125.v1.Issue125Service.Baz"
)

// Issue125ServiceClient describes a client for a(n) issue_125.v1.Issue125Service worker
type Issue125ServiceClient interface {
	// Foo executes a(n) issue_125.v1.Issue125Service.Foo workflow and blocks until error or response received
	Foo(ctx context.Context, req *FooInput, opts ...*FooOptions) (*FooOutput, error)

	// FooAsync starts a(n) issue_125.v1.Issue125Service.Foo workflow and returns a handle to the workflow run
	FooAsync(ctx context.Context, req *FooInput, opts ...*FooOptions) (FooRun, error)

	// GetFoo retrieves a handle to an existing issue_125.v1.Issue125Service.Foo workflow execution
	GetFoo(ctx context.Context, workflowID string, runID string) FooRun

	// CancelWorkflow requests cancellation of an existing workflow execution
	CancelWorkflow(ctx context.Context, workflowID string, runID string) error

	// TerminateWorkflow an existing workflow execution
	TerminateWorkflow(ctx context.Context, workflowID string, runID string, reason string, details ...interface{}) error

	// Bar executes a(n) issue_125.v1.Issue125Service.Bar update and blocks until update completion
	Bar(ctx context.Context, workflowID string, runID string, req *BarInput, opts ...*BarOptions) (*BarOutput, error)

	// BarAsync starts a(n) issue_125.v1.Issue125Service.Bar update and returns a handle to the workflow update
	BarAsync(ctx context.Context, workflowID string, runID string, req *BarInput, opts ...*BarOptions) (BarHandle, error)

	// GetBar retrieves a handle to an existing issue_125.v1.Issue125Service.Bar update
	GetBar(ctx context.Context, req client.GetWorkflowUpdateHandleOptions) (BarHandle, error)

	// Baz executes a(n) issue_125.v1.Issue125Service.Baz update and blocks until update completion
	Baz(ctx context.Context, workflowID string, runID string, req *BazInput, opts ...*BazOptions) (*BazOutput, error)

	// BazAsync starts a(n) issue_125.v1.Issue125Service.Baz update and returns a handle to the workflow update
	BazAsync(ctx context.Context, workflowID string, runID string, req *BazInput, opts ...*BazOptions) (BazHandle, error)

	// GetBaz retrieves a handle to an existing issue_125.v1.Issue125Service.Baz update
	GetBaz(ctx context.Context, req client.GetWorkflowUpdateHandleOptions) (BazHandle, error)
}

// issue125ServiceClient implements a temporal client for a issue_125.v1.Issue125Service service
type issue125ServiceClient struct {
	client client.Client
	log    *slog.Logger
}

// NewIssue125ServiceClient initializes a new issue_125.v1.Issue125Service client
func NewIssue125ServiceClient(c client.Client, options ...*issue125ServiceClientOptions) Issue125ServiceClient {
	var cfg *issue125ServiceClientOptions
	if len(options) > 0 {
		cfg = options[0]
	} else {
		cfg = NewIssue125ServiceClientOptions()
	}
	return &issue125ServiceClient{
		client: c,
		log:    cfg.getLogger(),
	}
}

// NewIssue125ServiceClientWithOptions initializes a new Issue125Service client with the given options
func NewIssue125ServiceClientWithOptions(c client.Client, opts client.Options, options ...*issue125ServiceClientOptions) (Issue125ServiceClient, error) {
	var err error
	c, err = client.NewClientFromExisting(c, opts)
	if err != nil {
		return nil, fmt.Errorf("error initializing client with options: %w", err)
	}
	var cfg *issue125ServiceClientOptions
	if len(options) > 0 {
		cfg = options[0]
	} else {
		cfg = NewIssue125ServiceClientOptions()
	}
	return &issue125ServiceClient{
		client: c,
		log:    cfg.getLogger(),
	}, nil
}

// issue125ServiceClientOptions describes optional runtime configuration for a Issue125ServiceClient
type issue125ServiceClientOptions struct {
	log *slog.Logger
}

// NewIssue125ServiceClientOptions initializes a new issue125ServiceClientOptions value
func NewIssue125ServiceClientOptions() *issue125ServiceClientOptions {
	return &issue125ServiceClientOptions{}
}

// WithLogger can be used to override the default logger
func (opts *issue125ServiceClientOptions) WithLogger(l *slog.Logger) *issue125ServiceClientOptions {
	if l != nil {
		opts.log = l
	}
	return opts
}

// getLogger returns the configured logger, or the default logger
func (opts *issue125ServiceClientOptions) getLogger() *slog.Logger {
	if opts != nil && opts.log != nil {
		return opts.log
	}
	return slog.Default()
}

// issue_125.v1.Issue125Service.Foo executes a issue_125.v1.Issue125Service.Foo workflow and blocks until error or response received
func (c *issue125ServiceClient) Foo(ctx context.Context, req *FooInput, options ...*FooOptions) (*FooOutput, error) {
	run, err := c.FooAsync(ctx, req, options...)
	if err != nil {
		return nil, err
	}
	return run.Get(ctx)
}

// FooAsync starts a(n) issue_125.v1.Issue125Service.Foo workflow and returns a handle to the workflow run
func (c *issue125ServiceClient) FooAsync(ctx context.Context, req *FooInput, options ...*FooOptions) (FooRun, error) {
	var o *FooOptions
	if len(options) > 0 && options[0] != nil {
		o = options[0]
	} else {
		o = NewFooOptions()
	}
	opts, err := o.Build(req.ProtoReflect())
	if err != nil {
		return nil, fmt.Errorf("error initializing client.StartWorkflowOptions: %w", err)
	}
	run, err := c.client.ExecuteWorkflow(ctx, opts, FooWorkflowName, req)
	if err != nil {
		return nil, err
	}
	if run == nil {
		return nil, errors.New("execute workflow returned nil run")
	}
	return &fooRun{
		client: c,
		run:    run,
	}, nil
}

// GetFoo fetches an existing issue_125.v1.Issue125Service.Foo execution
func (c *issue125ServiceClient) GetFoo(ctx context.Context, workflowID string, runID string) FooRun {
	return &fooRun{
		client: c,
		run:    c.client.GetWorkflow(ctx, workflowID, runID),
	}
}

// CancelWorkflow requests cancellation of an existing workflow execution
func (c *issue125ServiceClient) CancelWorkflow(ctx context.Context, workflowID string, runID string) error {
	return c.client.CancelWorkflow(ctx, workflowID, runID)
}

// TerminateWorkflow terminates an existing workflow execution
func (c *issue125ServiceClient) TerminateWorkflow(ctx context.Context, workflowID string, runID string, reason string, details ...interface{}) error {
	return c.client.TerminateWorkflow(ctx, workflowID, runID, reason, details...)
}

// issue_125.v1.Issue125Service.Bar sends a(n) issue_125.v1.Issue125Service.Bar update to an existing workflow
func (c *issue125ServiceClient) Bar(ctx context.Context, workflowID string, runID string, req *BarInput, opts ...*BarOptions) (*BarOutput, error) {
	// initialize update options
	o := NewBarOptions()
	if len(opts) > 0 && opts[0].Options != nil {
		o = opts[0]
	}

	// call sync update with WorkflowUpdateStageCompleted wait policy
	handle, err := c.BarAsync(ctx, workflowID, runID, req, o.WithWaitPolicy(client.WorkflowUpdateStageCompleted))
	if err != nil {
		return nil, err
	}

	// block on update completion
	return handle.Get(ctx)
}

// issue_125.v1.Issue125Service.Bar sends a(n) issue_125.v1.Issue125Service.Bar update to an existing workflow
func (c *issue125ServiceClient) BarAsync(ctx context.Context, workflowID string, runID string, req *BarInput, opts ...*BarOptions) (BarHandle, error) {
	// initialize update options
	var o *BarOptions
	if len(opts) > 0 && opts[0] != nil {
		o = opts[0]
	} else {
		o = NewBarOptions()
	}

	// build UpdateWorkflowOptions
	options, err := o.Build(workflowID, runID, req)
	if err != nil {
		return nil, fmt.Errorf("error initializing UpdateWorkflowWithOptions: %w", err)
	}

	// update workflow
	handle, err := c.client.UpdateWorkflow(ctx, *options)
	if err != nil {
		return nil, err
	}
	return &barHandle{client: c, handle: handle}, nil
}

// GetBar retrieves a handle to an existing issue_125.v1.Issue125Service.Bar update
func (c *issue125ServiceClient) GetBar(ctx context.Context, req client.GetWorkflowUpdateHandleOptions) (BarHandle, error) {
	return &barHandle{
		client: c,
		handle: c.client.GetWorkflowUpdateHandle(req),
	}, nil
}

// issue_125.v1.Issue125Service.Baz sends a(n) issue_125.v1.Issue125Service.Baz update to an existing workflow
func (c *issue125ServiceClient) Baz(ctx context.Context, workflowID string, runID string, req *BazInput, opts ...*BazOptions) (*BazOutput, error) {
	// initialize update options
	o := NewBazOptions()
	if len(opts) > 0 && opts[0].Options != nil {
		o = opts[0]
	}

	// call sync update with WorkflowUpdateStageCompleted wait policy
	handle, err := c.BazAsync(ctx, workflowID, runID, req, o.WithWaitPolicy(client.WorkflowUpdateStageCompleted))
	if err != nil {
		return nil, err
	}

	// block on update completion
	return handle.Get(ctx)
}

// issue_125.v1.Issue125Service.Baz sends a(n) issue_125.v1.Issue125Service.Baz update to an existing workflow
func (c *issue125ServiceClient) BazAsync(ctx context.Context, workflowID string, runID string, req *BazInput, opts ...*BazOptions) (BazHandle, error) {
	// initialize update options
	var o *BazOptions
	if len(opts) > 0 && opts[0] != nil {
		o = opts[0]
	} else {
		o = NewBazOptions()
	}

	// build UpdateWorkflowOptions
	options, err := o.Build(workflowID, runID, req)
	if err != nil {
		return nil, fmt.Errorf("error initializing UpdateWorkflowWithOptions: %w", err)
	}

	// update workflow
	handle, err := c.client.UpdateWorkflow(ctx, *options)
	if err != nil {
		return nil, err
	}
	return &bazHandle{client: c, handle: handle}, nil
}

// GetBaz retrieves a handle to an existing issue_125.v1.Issue125Service.Baz update
func (c *issue125ServiceClient) GetBaz(ctx context.Context, req client.GetWorkflowUpdateHandleOptions) (BazHandle, error) {
	return &bazHandle{
		client: c,
		handle: c.client.GetWorkflowUpdateHandle(req),
	}, nil
}

// FooOptions provides configuration for a issue_125.v1.Issue125Service.Foo workflow operation
type FooOptions struct {
	options                  client.StartWorkflowOptions
	executionTimeout         *time.Duration
	id                       *string
	idReusePolicy            enumsv1.WorkflowIdReusePolicy
	retryPolicy              *temporal.RetryPolicy
	runTimeout               *time.Duration
	searchAttributes         map[string]any
	taskQueue                *string
	taskTimeout              *time.Duration
	workflowIdConflictPolicy enumsv1.WorkflowIdConflictPolicy
}

// NewFooOptions initializes a new FooOptions value
func NewFooOptions() *FooOptions {
	return &FooOptions{}
}

// Build initializes a new go.temporal.io/sdk/client.StartWorkflowOptions value with defaults and overrides applied
func (o *FooOptions) Build(req protoreflect.Message) (client.StartWorkflowOptions, error) {
	opts := o.options
	if v := o.id; v != nil {
		opts.ID = *v
	} else if opts.ID == "" {
		id, err := expression.EvalExpression(FooIdexpression, req)
		if err != nil {
			return opts, fmt.Errorf("error evaluating id expression for %q workflow: %w", FooWorkflowName, err)
		}
		opts.ID = id
	}
	if v := o.idReusePolicy; v != enumsv1.WORKFLOW_ID_REUSE_POLICY_UNSPECIFIED {
		opts.WorkflowIDReusePolicy = v
	}
	if v := o.workflowIdConflictPolicy; v != enumsv1.WORKFLOW_ID_CONFLICT_POLICY_UNSPECIFIED {
		opts.WorkflowIDConflictPolicy = v
	}
	if v := o.taskQueue; v != nil {
		opts.TaskQueue = *v
	} else if opts.TaskQueue == "" {
		opts.TaskQueue = Issue125ServiceTaskQueue
	}
	if v := o.retryPolicy; v != nil {
		opts.RetryPolicy = v
	}
	if v := o.searchAttributes; v != nil {
		opts.SearchAttributes = o.searchAttributes
	}
	if v := o.executionTimeout; v != nil {
		opts.WorkflowExecutionTimeout = *v
	}
	if v := o.runTimeout; v != nil {
		opts.WorkflowRunTimeout = *v
	}
	if v := o.taskTimeout; v != nil {
		opts.WorkflowTaskTimeout = *v
	}
	return opts, nil
}

// WithStartWorkflowOptions sets the initial go.temporal.io/sdk/client.StartWorkflowOptions
func (o *FooOptions) WithStartWorkflowOptions(options client.StartWorkflowOptions) *FooOptions {
	o.options = options
	return o
}

// WithExecutionTimeout sets the WorkflowExecutionTimeout value
func (o *FooOptions) WithExecutionTimeout(d time.Duration) *FooOptions {
	o.executionTimeout = &d
	return o
}

// WithID sets the ID value
func (o *FooOptions) WithID(id string) *FooOptions {
	o.id = &id
	return o
}

// WithIDReusePolicy sets the WorkflowIDReusePolicy value
func (o *FooOptions) WithIDReusePolicy(policy enumsv1.WorkflowIdReusePolicy) *FooOptions {
	o.idReusePolicy = policy
	return o
}

// WithRetryPolicy sets the RetryPolicy value
func (o *FooOptions) WithRetryPolicy(policy *temporal.RetryPolicy) *FooOptions {
	o.retryPolicy = policy
	return o
}

// WithRunTimeout sets the WorkflowRunTimeout value
func (o *FooOptions) WithRunTimeout(d time.Duration) *FooOptions {
	o.runTimeout = &d
	return o
}

// WithSearchAttributes sets the SearchAttributes value
func (o *FooOptions) WithSearchAttributes(sa map[string]any) *FooOptions {
	o.searchAttributes = sa
	return o
}

// WithTaskTimeout sets the WorkflowTaskTimeout value
func (o *FooOptions) WithTaskTimeout(d time.Duration) *FooOptions {
	o.taskTimeout = &d
	return o
}

// WithTaskQueue sets the TaskQueue value
func (o *FooOptions) WithTaskQueue(tq string) *FooOptions {
	o.taskQueue = &tq
	return o
}

// WithWorkflowIdConflictPolicy sets the WorkflowIdConflictPolicy value
func (o *FooOptions) WithWorkflowIdConflictPolicy(policy enumsv1.WorkflowIdConflictPolicy) *FooOptions {
	o.workflowIdConflictPolicy = policy
	return o
}

// FooRun describes a(n) issue_125.v1.Issue125Service.Foo workflow run
type FooRun interface {
	// ID returns the workflow ID
	ID() string

	// RunID returns the workflow instance ID
	RunID() string

	// Run returns the inner client.WorkflowRun
	Run() client.WorkflowRun

	// Get blocks until the workflow is complete and returns the result
	Get(ctx context.Context) (*FooOutput, error)

	// Cancel requests cancellation of a workflow in execution, returning an error if applicable
	Cancel(ctx context.Context) error

	// Terminate terminates a workflow in execution, returning an error if applicable
	Terminate(ctx context.Context, reason string, details ...interface{}) error

	// issue_125.v1.Issue125Service.Bar executes a(n) issue_125.v1.Issue125Service.Bar update
	Bar(ctx context.Context, req *BarInput, opts ...*BarOptions) (*BarOutput, error)

	// issue_125.v1.Issue125Service.BarAsync sends a(n) issue_125.v1.Issue125Service.Bar update to the workflow
	BarAsync(ctx context.Context, req *BarInput, opts ...*BarOptions) (BarHandle, error)

	// issue_125.v1.Issue125Service.Baz executes a(n) issue_125.v1.Issue125Service.Baz update
	Baz(ctx context.Context, req *BazInput, opts ...*BazOptions) (*BazOutput, error)

	// issue_125.v1.Issue125Service.BazAsync sends a(n) issue_125.v1.Issue125Service.Baz update to the workflow
	BazAsync(ctx context.Context, req *BazInput, opts ...*BazOptions) (BazHandle, error)
}

// fooRun provides an internal implementation of a(n) FooRunRun
type fooRun struct {
	client *issue125ServiceClient
	run    client.WorkflowRun
}

// ID returns the workflow ID
func (r *fooRun) ID() string {
	return r.run.GetID()
}

// Run returns the inner client.WorkflowRun
func (r *fooRun) Run() client.WorkflowRun {
	return r.run
}

// RunID returns the execution ID
func (r *fooRun) RunID() string {
	return r.run.GetRunID()
}

// Cancel requests cancellation of a workflow in execution, returning an error if applicable
func (r *fooRun) Cancel(ctx context.Context) error {
	return r.client.CancelWorkflow(ctx, r.ID(), r.RunID())
}

// Get blocks until the workflow is complete, returning the result if applicable
func (r *fooRun) Get(ctx context.Context) (*FooOutput, error) {
	var resp FooOutput
	if err := r.run.Get(ctx, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// Terminate terminates a workflow in execution, returning an error if applicable
func (r *fooRun) Terminate(ctx context.Context, reason string, details ...interface{}) error {
	return r.client.TerminateWorkflow(ctx, r.ID(), r.RunID(), reason, details...)
}

// issue_125.v1.Issue125Service.Bar executes a(n) issue_125.v1.Issue125Service.Bar workflow update
func (r *fooRun) Bar(ctx context.Context, req *BarInput, opts ...*BarOptions) (*BarOutput, error) {
	return r.client.Bar(ctx, r.ID(), r.RunID(), req, opts...)
}

// BarAsync start a(n) issue_125.v1.Issue125Service.Bar workflow update and returns a handle to the update
func (r *fooRun) BarAsync(ctx context.Context, req *BarInput, opts ...*BarOptions) (BarHandle, error) {
	return r.client.BarAsync(ctx, r.ID(), r.RunID(), req, opts...)
}

// issue_125.v1.Issue125Service.Baz executes a(n) issue_125.v1.Issue125Service.Baz workflow update
func (r *fooRun) Baz(ctx context.Context, req *BazInput, opts ...*BazOptions) (*BazOutput, error) {
	return r.client.Baz(ctx, r.ID(), r.RunID(), req, opts...)
}

// BazAsync start a(n) issue_125.v1.Issue125Service.Baz workflow update and returns a handle to the update
func (r *fooRun) BazAsync(ctx context.Context, req *BazInput, opts ...*BazOptions) (BazHandle, error) {
	return r.client.BazAsync(ctx, r.ID(), r.RunID(), req, opts...)
}

// BarHandle describes a(n) issue_125.v1.Issue125Service.Bar update handle
type BarHandle interface {
	// WorkflowID returns the workflow ID
	WorkflowID() string
	// RunID returns the workflow instance ID
	RunID() string
	// UpdateID returns the update ID
	UpdateID() string
	// Get blocks until the workflow is complete and returns the result
	Get(ctx context.Context) (*BarOutput, error)
}

// barHandle provides an internal implementation of a(n) BarHandle
type barHandle struct {
	client *issue125ServiceClient
	handle client.WorkflowUpdateHandle
}

// WorkflowID returns the workflow ID
func (h *barHandle) WorkflowID() string {
	return h.handle.WorkflowID()
}

// RunID returns the execution ID
func (h *barHandle) RunID() string {
	return h.handle.RunID()
}

// UpdateID returns the update ID
func (h *barHandle) UpdateID() string {
	return h.handle.UpdateID()
}

// Get blocks until the update wait policy is met, returning the result if applicable
func (h *barHandle) Get(ctx context.Context) (*BarOutput, error) {
	var resp BarOutput
	var err error
	doneCh := make(chan struct{})
	gctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	go func() {
		for {
			var deadlineExceeded *serviceerror.DeadlineExceeded
			if err = h.handle.Get(gctx, &resp); err != nil && ctx.Err() == nil && (errors.As(err, &deadlineExceeded) || strings.Contains(err.Error(), context.DeadlineExceeded.Error())) {
				continue
			}
			break
		}
		close(doneCh)
	}()

	select {
	case <-ctx.Done():
		return nil, ctx.Err()
	case <-doneCh:
		if err != nil {
			return nil, err
		}
		return &resp, nil
	}
}

// BarOptions provides configuration for a issue_125.v1.Issue125Service.Bar update operation
type BarOptions struct {
	Options    *client.UpdateWorkflowOptions
	id         *string
	waitPolicy client.WorkflowUpdateStage
}

// NewBarOptions initializes a new BarOptions value
func NewBarOptions() *BarOptions {
	return &BarOptions{Options: &client.UpdateWorkflowOptions{}}
}

// Build initializes a new client.UpdateWorkflowOptions with defaults and overrides applied
func (o *BarOptions) Build(workflowID string, runID string, req *BarInput) (opts *client.UpdateWorkflowOptions, err error) {
	// use user-provided UpdateWorkflowOptions if exists
	if o.Options != nil {
		opts = o.Options
	} else {
		opts = &client.UpdateWorkflowOptions{}
	}

	// set constants
	opts.Args = []any{req}
	opts.RunID = runID
	opts.UpdateName = BarUpdateName
	opts.WorkflowID = workflowID

	// set UpdateID
	if v := o.id; v != nil {
		opts.UpdateID = *v
	}

	// set WaitPolicy
	if v := o.waitPolicy; v != client.WorkflowUpdateStageUnspecified {
		opts.WaitForStage = v
	} else if opts.WaitForStage == client.WorkflowUpdateStageUnspecified {
		opts.WaitForStage = client.WorkflowUpdateStageAccepted
	}
	return opts, nil
}

// WithUpdateID sets the UpdateID
func (o *BarOptions) WithUpdateID(id string) *BarOptions {
	o.id = &id
	return o
}

// WithUpdateWorkflowOptions sets the initial client.UpdateWorkflowOptions
func (o *BarOptions) WithUpdateWorkflowOptions(options client.UpdateWorkflowOptions) *BarOptions {
	o.Options = &options
	return o
}

// WithWaitPolicy sets the WaitPolicy
func (o *BarOptions) WithWaitPolicy(policy client.WorkflowUpdateStage) *BarOptions {
	o.waitPolicy = policy
	return o
}

// BazHandle describes a(n) issue_125.v1.Issue125Service.Baz update handle
type BazHandle interface {
	// WorkflowID returns the workflow ID
	WorkflowID() string
	// RunID returns the workflow instance ID
	RunID() string
	// UpdateID returns the update ID
	UpdateID() string
	// Get blocks until the workflow is complete and returns the result
	Get(ctx context.Context) (*BazOutput, error)
}

// bazHandle provides an internal implementation of a(n) BazHandle
type bazHandle struct {
	client *issue125ServiceClient
	handle client.WorkflowUpdateHandle
}

// WorkflowID returns the workflow ID
func (h *bazHandle) WorkflowID() string {
	return h.handle.WorkflowID()
}

// RunID returns the execution ID
func (h *bazHandle) RunID() string {
	return h.handle.RunID()
}

// UpdateID returns the update ID
func (h *bazHandle) UpdateID() string {
	return h.handle.UpdateID()
}

// Get blocks until the update wait policy is met, returning the result if applicable
func (h *bazHandle) Get(ctx context.Context) (*BazOutput, error) {
	var resp BazOutput
	var err error
	doneCh := make(chan struct{})
	gctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	go func() {
		for {
			var deadlineExceeded *serviceerror.DeadlineExceeded
			if err = h.handle.Get(gctx, &resp); err != nil && ctx.Err() == nil && (errors.As(err, &deadlineExceeded) || strings.Contains(err.Error(), context.DeadlineExceeded.Error())) {
				continue
			}
			break
		}
		close(doneCh)
	}()

	select {
	case <-ctx.Done():
		return nil, ctx.Err()
	case <-doneCh:
		if err != nil {
			return nil, err
		}
		return &resp, nil
	}
}

// BazOptions provides configuration for a issue_125.v1.Issue125Service.Baz update operation
type BazOptions struct {
	Options    *client.UpdateWorkflowOptions
	id         *string
	waitPolicy client.WorkflowUpdateStage
}

// NewBazOptions initializes a new BazOptions value
func NewBazOptions() *BazOptions {
	return &BazOptions{Options: &client.UpdateWorkflowOptions{}}
}

// Build initializes a new client.UpdateWorkflowOptions with defaults and overrides applied
func (o *BazOptions) Build(workflowID string, runID string, req *BazInput) (opts *client.UpdateWorkflowOptions, err error) {
	// use user-provided UpdateWorkflowOptions if exists
	if o.Options != nil {
		opts = o.Options
	} else {
		opts = &client.UpdateWorkflowOptions{}
	}

	// set constants
	opts.Args = []any{req}
	opts.RunID = runID
	opts.UpdateName = BazUpdateName
	opts.WorkflowID = workflowID

	// set UpdateID
	if v := o.id; v != nil {
		opts.UpdateID = *v
	}

	// set WaitPolicy
	if v := o.waitPolicy; v != client.WorkflowUpdateStageUnspecified {
		opts.WaitForStage = v
	} else if opts.WaitForStage == client.WorkflowUpdateStageUnspecified {
		opts.WaitForStage = client.WorkflowUpdateStageAccepted
	}
	return opts, nil
}

// WithUpdateID sets the UpdateID
func (o *BazOptions) WithUpdateID(id string) *BazOptions {
	o.id = &id
	return o
}

// WithUpdateWorkflowOptions sets the initial client.UpdateWorkflowOptions
func (o *BazOptions) WithUpdateWorkflowOptions(options client.UpdateWorkflowOptions) *BazOptions {
	o.Options = &options
	return o
}

// WithWaitPolicy sets the WaitPolicy
func (o *BazOptions) WithWaitPolicy(policy client.WorkflowUpdateStage) *BazOptions {
	o.waitPolicy = policy
	return o
}

// Reference to generated workflow functions
var (
	// issue125ServiceRegistrationMutex is a mutex for registering issue_125.v1.Issue125Service workflows
	issue125ServiceRegistrationMutex sync.Mutex
	// FooFunction implements a "issue_125.v1.Issue125Service.Foo" workflow
	FooFunction func(workflow.Context, *FooInput) (*FooOutput, error)
)

// Issue125ServiceWorkflowFunctions describes a mockable dependency for inlining workflows within other workflows
type (
	// Issue125ServiceWorkflowFunctions describes a mockable dependency for inlining workflows within other workflows
	Issue125ServiceWorkflowFunctions interface {
		// Foo executes a "issue_125.v1.Issue125Service.Foo" workflow inline
		Foo(workflow.Context, *FooInput) (*FooOutput, error)
	}
	// issue125ServiceWorkflowFunctions provides an internal Issue125ServiceWorkflowFunctions implementation
	issue125ServiceWorkflowFunctions struct{}
)

func NewIssue125ServiceWorkflowFunctions() Issue125ServiceWorkflowFunctions {
	return &issue125ServiceWorkflowFunctions{}
}

// Foo executes a "issue_125.v1.Issue125Service.Foo" workflow inline
func (f *issue125ServiceWorkflowFunctions) Foo(ctx workflow.Context, req *FooInput) (*FooOutput, error) {
	if FooFunction == nil {
		return nil, errors.New("Foo requires workflow registration via RegisterIssue125ServiceWorkflows or RegisterFooWorkflow")
	}
	return FooFunction(ctx, req)
}

// Issue125ServiceWorkflows provides methods for initializing new issue_125.v1.Issue125Service workflow values
type Issue125ServiceWorkflows interface {
	// Foo initializes a new a(n) FooWorkflow implementation
	Foo(ctx workflow.Context, input *FooWorkflowInput) (FooWorkflow, error)
}

// RegisterIssue125ServiceWorkflows registers issue_125.v1.Issue125Service workflows with the given worker
func RegisterIssue125ServiceWorkflows(r worker.WorkflowRegistry, workflows Issue125ServiceWorkflows) {
	RegisterFooWorkflow(r, workflows.Foo)
}

// RegisterFooWorkflow registers a issue_125.v1.Issue125Service.Foo workflow with the given worker
func RegisterFooWorkflow(r worker.WorkflowRegistry, wf func(workflow.Context, *FooWorkflowInput) (FooWorkflow, error)) {
	issue125ServiceRegistrationMutex.Lock()
	defer issue125ServiceRegistrationMutex.Unlock()
	FooFunction = buildFoo(wf)
	r.RegisterWorkflowWithOptions(FooFunction, workflow.RegisterOptions{Name: FooWorkflowName})
}

// buildFoo converts a Foo workflow struct into a valid workflow function
func buildFoo(ctor func(workflow.Context, *FooWorkflowInput) (FooWorkflow, error)) func(workflow.Context, *FooInput) (*FooOutput, error) {
	return func(ctx workflow.Context, req *FooInput) (*FooOutput, error) {
		input := &FooWorkflowInput{
			Req: req,
		}
		wf, err := ctor(ctx, input)
		if err != nil {
			return nil, err
		}
		if initializable, ok := wf.(helpers.Initializable); ok {
			if err := initializable.Initialize(ctx); err != nil {
				return nil, err
			}
		}
		{
			opts := workflow.UpdateHandlerOptions{}
			if err := workflow.SetUpdateHandlerWithOptions(ctx, BarUpdateName, wf.Bar, opts); err != nil {
				return nil, err
			}
		}
		{
			opts := workflow.UpdateHandlerOptions{}
			if err := workflow.SetUpdateHandlerWithOptions(ctx, BazUpdateName, wf.Baz, opts); err != nil {
				return nil, err
			}
		}
		return wf.Execute(ctx)
	}
}

// FooWorkflowInput describes the input to a(n) issue_125.v1.Issue125Service.Foo workflow constructor
type FooWorkflowInput struct {
	Req *FooInput
}

// FooWorkflow describes a(n) issue_125.v1.Issue125Service.Foo workflow implementation
//
// workflow details: (id: "foo/${! id }")
type FooWorkflow interface {
	// Execute defines the entrypoint to a(n) issue_125.v1.Issue125Service.Foo workflow
	Execute(ctx workflow.Context) (*FooOutput, error)

	// issue_125.v1.Issue125Service.Bar implements a(n) issue_125.v1.Issue125Service.Bar update handler
	Bar(workflow.Context, *BarInput) (*BarOutput, error)

	// issue_125.v1.Issue125Service.Baz implements a(n) issue_125.v1.Issue125Service.Baz update handler
	Baz(workflow.Context, *BazInput) (*BazOutput, error)
}

// FooChild executes a child issue_125.v1.Issue125Service.Foo workflow and blocks until error or response received
func FooChild(ctx workflow.Context, req *FooInput, options ...*FooChildOptions) (*FooOutput, error) {
	childRun, err := FooChildAsync(ctx, req, options...)
	if err != nil {
		return nil, err
	}
	return childRun.Get(ctx)
}

// FooChildAsync starts a child issue_125.v1.Issue125Service.Foo workflow and returns a handle to the child workflow run
func FooChildAsync(ctx workflow.Context, req *FooInput, options ...*FooChildOptions) (*FooChildRun, error) {
	var o *FooChildOptions
	if len(options) > 0 && options[0] != nil {
		o = options[0]
	} else {
		o = NewFooChildOptions()
	}
	opts, err := o.Build(ctx, req.ProtoReflect())
	if err != nil {
		return nil, fmt.Errorf("error initializing workflow.ChildWorkflowOptions: %w", err)
	}
	ctx = workflow.WithChildOptions(ctx, opts)
	if o.dc != nil {
		ctx = workflow.WithDataConverter(ctx, o.dc)
	}
	return &FooChildRun{Future: workflow.ExecuteChildWorkflow(ctx, FooWorkflowName, req)}, nil
}

// FooChildOptions provides configuration for a child issue_125.v1.Issue125Service.Foo workflow operation
type FooChildOptions struct {
	options                  workflow.ChildWorkflowOptions
	executionTimeout         *time.Duration
	id                       *string
	idReusePolicy            enumsv1.WorkflowIdReusePolicy
	retryPolicy              *temporal.RetryPolicy
	runTimeout               *time.Duration
	searchAttributes         map[string]any
	taskQueue                *string
	taskTimeout              *time.Duration
	workflowIdConflictPolicy enumsv1.WorkflowIdConflictPolicy
	dc                       converter.DataConverter
	parentClosePolicy        enumsv1.ParentClosePolicy
	waitForCancellation      *bool
}

// NewFooChildOptions initializes a new FooChildOptions value
func NewFooChildOptions() *FooChildOptions {
	return &FooChildOptions{}
}

// Build initializes a new go.temporal.io/sdk/workflow.ChildWorkflowOptions value with defaults and overrides applied
func (o *FooChildOptions) Build(ctx workflow.Context, req protoreflect.Message) (workflow.ChildWorkflowOptions, error) {
	opts := o.options
	if v := o.id; v != nil {
		opts.WorkflowID = *v
	} else if opts.WorkflowID == "" {
		// wrap expression evaluation in local activity
		// more info: https://cludden.github.io/protoc-gen-go-temporal/docs/guides/patches#pv_64-expression-evaluation-local-activity
		if workflow.GetVersion(ctx, "cludden_protoc-gen-go-temporal_64_expression-evaluation-local-activity", workflow.DefaultVersion, 1) == 1 {
			lao := workflow.GetLocalActivityOptions(ctx)
			lao.ScheduleToCloseTimeout = time.Second * 10
			if err := workflow.ExecuteLocalActivity(workflow.WithLocalActivityOptions(ctx, lao), func(ctx context.Context) (string, error) {
				id, err := expression.EvalExpression(FooIdexpression, req)
				if err != nil {
					return "", fmt.Errorf("error evaluating id expression for %q workflow: %w", FooWorkflowName, err)
				}
				return id, nil
			}).Get(ctx, &opts.WorkflowID); err != nil {
				return opts, fmt.Errorf("error evaluating id expression for %q workflow: %w", FooWorkflowName, err)
			}
		} else {
			id, err := expression.EvalExpression(FooIdexpression, req)
			if err != nil {
				return opts, fmt.Errorf("error evaluating id expression for %q workflow: %w", FooWorkflowName, err)
			}
			opts.WorkflowID = id
		}
	}
	if v := o.idReusePolicy; v != enumsv1.WORKFLOW_ID_REUSE_POLICY_UNSPECIFIED {
		opts.WorkflowIDReusePolicy = v
	}
	if v := o.taskQueue; v != nil {
		opts.TaskQueue = *v
	} else if opts.TaskQueue == "" {
		opts.TaskQueue = Issue125ServiceTaskQueue
	}
	if v := o.retryPolicy; v != nil {
		opts.RetryPolicy = v
	}
	if v := o.searchAttributes; v != nil {
		opts.SearchAttributes = o.searchAttributes
	}
	if v := o.executionTimeout; v != nil {
		opts.WorkflowExecutionTimeout = *v
	}
	if v := o.runTimeout; v != nil {
		opts.WorkflowRunTimeout = *v
	}
	if v := o.taskTimeout; v != nil {
		opts.WorkflowTaskTimeout = *v
	}
	if v := o.parentClosePolicy; v != enumsv1.PARENT_CLOSE_POLICY_UNSPECIFIED {
		opts.ParentClosePolicy = v
	}
	if v := o.waitForCancellation; v != nil {
		opts.WaitForCancellation = *v
	}
	return opts, nil
}

// WithChildWorkflowOptions sets the initial go.temporal.io/sdk/workflow.ChildWorkflowOptions
func (o *FooChildOptions) WithChildWorkflowOptions(options workflow.ChildWorkflowOptions) *FooChildOptions {
	o.options = options
	return o
}

// WithDataConverter registers a DataConverter for the child workflow
func (o *FooChildOptions) WithDataConverter(dc converter.DataConverter) *FooChildOptions {
	o.dc = dc
	return o
}

// WithExecutionTimeout sets the WorkflowExecutionTimeout value
func (o *FooChildOptions) WithExecutionTimeout(d time.Duration) *FooChildOptions {
	o.executionTimeout = &d
	return o
}

// WithID sets the WorkflowID value
func (o *FooChildOptions) WithID(id string) *FooChildOptions {
	o.id = &id
	return o
}

// WithIDReusePolicy sets the WorkflowIDReusePolicy value
func (o *FooChildOptions) WithIDReusePolicy(policy enumsv1.WorkflowIdReusePolicy) *FooChildOptions {
	o.idReusePolicy = policy
	return o
}

// WithParentClosePolicy sets the WorkflowIDReusePolicy value
func (o *FooChildOptions) WithParentClosePolicy(policy enumsv1.ParentClosePolicy) *FooChildOptions {
	o.parentClosePolicy = policy
	return o
}

// WithRetryPolicy sets the RetryPolicy value
func (o *FooChildOptions) WithRetryPolicy(policy *temporal.RetryPolicy) *FooChildOptions {
	o.retryPolicy = policy
	return o
}

// WithRunTimeout sets the WorkflowRunTimeout value
func (o *FooChildOptions) WithRunTimeout(d time.Duration) *FooChildOptions {
	o.runTimeout = &d
	return o
}

// WithSearchAttributes sets the SearchAttributes value
func (o *FooChildOptions) WithSearchAttributes(sa map[string]any) *FooChildOptions {
	o.searchAttributes = sa
	return o
}

// WithTaskTimeout sets the WorkflowTaskTimeout value
func (o *FooChildOptions) WithTaskTimeout(d time.Duration) *FooChildOptions {
	o.taskTimeout = &d
	return o
}

// WithTaskQueue sets the TaskQueue value
func (o *FooChildOptions) WithTaskQueue(tq string) *FooChildOptions {
	o.taskQueue = &tq
	return o
}

// WithWaitForCancellation sets the WaitForCancellation value
func (o *FooChildOptions) WithWaitForCancellation(wait bool) *FooChildOptions {
	o.waitForCancellation = &wait
	return o
}

// WithWorkflowIdConflictPolicy sets the WorkflowIdConflictPolicy value
func (o *FooChildOptions) WithWorkflowIdConflictPolicy(policy enumsv1.WorkflowIdConflictPolicy) *FooChildOptions {
	o.workflowIdConflictPolicy = policy
	return o
}

// FooChildRun describes a child Foo workflow run
type FooChildRun struct {
	Future workflow.ChildWorkflowFuture
}

// Get blocks until the workflow is completed, returning the response value
func (r *FooChildRun) Get(ctx workflow.Context) (*FooOutput, error) {
	var resp FooOutput
	if err := r.Future.Get(ctx, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// Select adds this completion to the selector. Callback can be nil.
func (r *FooChildRun) Select(sel workflow.Selector, fn func(*FooChildRun)) workflow.Selector {
	return sel.AddFuture(r.Future, func(workflow.Future) {
		if fn != nil {
			fn(r)
		}
	})
}

// SelectStart adds waiting for start to the selector. Callback can be nil.
func (r *FooChildRun) SelectStart(sel workflow.Selector, fn func(*FooChildRun)) workflow.Selector {
	return sel.AddFuture(r.Future.GetChildWorkflowExecution(), func(workflow.Future) {
		if fn != nil {
			fn(r)
		}
	})
}

// WaitStart waits for the child workflow to start
func (r *FooChildRun) WaitStart(ctx workflow.Context) (*workflow.Execution, error) {
	var exec workflow.Execution
	if err := r.Future.GetChildWorkflowExecution().Get(ctx, &exec); err != nil {
		return nil, err
	}
	return &exec, nil
}

// Issue125ServiceActivities describes available worker activities
type Issue125ServiceActivities interface{}

// RegisterIssue125ServiceActivities registers activities with a worker
func RegisterIssue125ServiceActivities(r worker.ActivityRegistry, activities Issue125ServiceActivities) {
}

// TestClient provides a testsuite-compatible Client
type TestIssue125ServiceClient struct {
	env       *testsuite.TestWorkflowEnvironment
	workflows Issue125ServiceWorkflows
}

var _ Issue125ServiceClient = &TestIssue125ServiceClient{}

// NewTestIssue125ServiceClient initializes a new TestIssue125ServiceClient value
func NewTestIssue125ServiceClient(env *testsuite.TestWorkflowEnvironment, workflows Issue125ServiceWorkflows, activities Issue125ServiceActivities) *TestIssue125ServiceClient {
	if workflows != nil {
		RegisterIssue125ServiceWorkflows(env, workflows)
	}
	if activities != nil {
		RegisterIssue125ServiceActivities(env, activities)
	}
	return &TestIssue125ServiceClient{env, workflows}
}

// Foo executes a(n) issue_125.v1.Issue125Service.Foo workflow in the test environment
func (c *TestIssue125ServiceClient) Foo(ctx context.Context, req *FooInput, opts ...*FooOptions) (*FooOutput, error) {
	run, err := c.FooAsync(ctx, req, opts...)
	if err != nil {
		return nil, err
	}
	return run.Get(ctx)
}

// FooAsync executes a(n) issue_125.v1.Issue125Service.Foo workflow in the test environment
func (c *TestIssue125ServiceClient) FooAsync(ctx context.Context, req *FooInput, options ...*FooOptions) (FooRun, error) {
	var o *FooOptions
	if len(options) > 0 && options[0] != nil {
		o = options[0]
	} else {
		o = NewFooOptions()
	}
	opts, err := o.Build(req.ProtoReflect())
	if err != nil {
		return nil, fmt.Errorf("error initializing client.StartWorkflowOptions: %w", err)
	}
	return &testFooRun{client: c, env: c.env, opts: &opts, req: req, workflows: c.workflows}, nil
}

// GetFoo is a noop
func (c *TestIssue125ServiceClient) GetFoo(ctx context.Context, workflowID string, runID string) FooRun {
	return &testFooRun{env: c.env, workflows: c.workflows}
}

// CancelWorkflow requests cancellation of an existing workflow execution
func (c *TestIssue125ServiceClient) CancelWorkflow(ctx context.Context, workflowID string, runID string) error {
	c.env.CancelWorkflow()
	return nil
}

// TerminateWorkflow terminates an existing workflow execution
func (c *TestIssue125ServiceClient) TerminateWorkflow(ctx context.Context, workflowID string, runID string, reason string, details ...interface{}) error {
	return c.CancelWorkflow(ctx, workflowID, runID)
}

// Bar executes a(n) issue_125.v1.Issue125Service.Bar update in the test environment
func (c *TestIssue125ServiceClient) Bar(ctx context.Context, workflowID string, runID string, req *BarInput, opts ...*BarOptions) (*BarOutput, error) {
	options := NewBarOptions()
	if len(opts) > 0 && opts[0].Options != nil {
		options = opts[0]
	}
	options.Options.WaitForStage = client.WorkflowUpdateStageCompleted
	handle, err := c.BarAsync(ctx, workflowID, runID, req, options)
	if err != nil {
		return nil, err
	}
	return handle.Get(ctx)
}

// BarAsync executes a(n) issue_125.v1.Issue125Service.Bar update in the test environment
func (c *TestIssue125ServiceClient) BarAsync(ctx context.Context, workflowID string, runID string, req *BarInput, opts ...*BarOptions) (BarHandle, error) {
	var o *BarOptions
	if len(opts) > 0 && opts[0] != nil {
		o = opts[0]
	} else {
		o = NewBarOptions()
	}
	options, err := o.Build(workflowID, runID, req)
	if err != nil {
		return nil, fmt.Errorf("error initializing UpdateWorkflowWithOptions: %w", err)
	}

	if options.UpdateID == "" {
		options.UpdateID = uuid.New().String()
	}

	uc := testutil.NewUpdateCallbacks()
	c.env.UpdateWorkflow(BarUpdateName, options.UpdateID, uc, req)
	return &testBarHandle{
		callbacks:  uc,
		env:        c.env,
		opts:       options,
		runID:      runID,
		workflowID: workflowID,
		req:        req,
	}, nil
}

// GetBar retrieves a handle to an existing issue_125.v1.Issue125Service.Bar update
func (c *TestIssue125ServiceClient) GetBar(ctx context.Context, req client.GetWorkflowUpdateHandleOptions) (BarHandle, error) {
	return nil, errors.New("unimplemented")
}

var _ BarHandle = &testBarHandle{}

// testBarHandle provides an internal implementation of a(n) BarHandle
type testBarHandle struct {
	callbacks  *testutil.UpdateCallbacks
	env        *testsuite.TestWorkflowEnvironment
	opts       *client.UpdateWorkflowOptions
	req        *BarInput
	runID      string
	workflowID string
}

// Get retrieves a test issue_125.v1.Issue125Service.Bar update result
func (h *testBarHandle) Get(ctx context.Context) (*BarOutput, error) {
	if resp, err := h.callbacks.Get(ctx); err != nil {
		return nil, err
	} else {
		return resp.(*BarOutput), nil
	}
}

// RunID implementation
func (h *testBarHandle) RunID() string {
	return h.runID
}

// UpdateID implementation
func (h *testBarHandle) UpdateID() string {
	if h.opts != nil {
		return h.opts.UpdateID
	}
	return ""
}

// WorkflowID implementation
func (h *testBarHandle) WorkflowID() string {
	return h.workflowID
}

// Baz executes a(n) issue_125.v1.Issue125Service.Baz update in the test environment
func (c *TestIssue125ServiceClient) Baz(ctx context.Context, workflowID string, runID string, req *BazInput, opts ...*BazOptions) (*BazOutput, error) {
	options := NewBazOptions()
	if len(opts) > 0 && opts[0].Options != nil {
		options = opts[0]
	}
	options.Options.WaitForStage = client.WorkflowUpdateStageCompleted
	handle, err := c.BazAsync(ctx, workflowID, runID, req, options)
	if err != nil {
		return nil, err
	}
	return handle.Get(ctx)
}

// BazAsync executes a(n) issue_125.v1.Issue125Service.Baz update in the test environment
func (c *TestIssue125ServiceClient) BazAsync(ctx context.Context, workflowID string, runID string, req *BazInput, opts ...*BazOptions) (BazHandle, error) {
	var o *BazOptions
	if len(opts) > 0 && opts[0] != nil {
		o = opts[0]
	} else {
		o = NewBazOptions()
	}
	options, err := o.Build(workflowID, runID, req)
	if err != nil {
		return nil, fmt.Errorf("error initializing UpdateWorkflowWithOptions: %w", err)
	}

	if options.UpdateID == "" {
		options.UpdateID = uuid.New().String()
	}

	uc := testutil.NewUpdateCallbacks()
	c.env.UpdateWorkflow(BazUpdateName, options.UpdateID, uc, req)
	return &testBazHandle{
		callbacks:  uc,
		env:        c.env,
		opts:       options,
		runID:      runID,
		workflowID: workflowID,
		req:        req,
	}, nil
}

// GetBaz retrieves a handle to an existing issue_125.v1.Issue125Service.Baz update
func (c *TestIssue125ServiceClient) GetBaz(ctx context.Context, req client.GetWorkflowUpdateHandleOptions) (BazHandle, error) {
	return nil, errors.New("unimplemented")
}

var _ BazHandle = &testBazHandle{}

// testBazHandle provides an internal implementation of a(n) BazHandle
type testBazHandle struct {
	callbacks  *testutil.UpdateCallbacks
	env        *testsuite.TestWorkflowEnvironment
	opts       *client.UpdateWorkflowOptions
	req        *BazInput
	runID      string
	workflowID string
}

// Get retrieves a test issue_125.v1.Issue125Service.Baz update result
func (h *testBazHandle) Get(ctx context.Context) (*BazOutput, error) {
	if resp, err := h.callbacks.Get(ctx); err != nil {
		return nil, err
	} else {
		return resp.(*BazOutput), nil
	}
}

// RunID implementation
func (h *testBazHandle) RunID() string {
	return h.runID
}

// UpdateID implementation
func (h *testBazHandle) UpdateID() string {
	if h.opts != nil {
		return h.opts.UpdateID
	}
	return ""
}

// WorkflowID implementation
func (h *testBazHandle) WorkflowID() string {
	return h.workflowID
}

var _ FooRun = &testFooRun{}

// testFooRun provides convenience methods for interacting with a(n) issue_125.v1.Issue125Service.Foo workflow in the test environment
type testFooRun struct {
	client    *TestIssue125ServiceClient
	env       *testsuite.TestWorkflowEnvironment
	isStarted atomic.Bool
	opts      *client.StartWorkflowOptions
	req       *FooInput
	workflows Issue125ServiceWorkflows
}

// Cancel requests cancellation of a workflow in execution, returning an error if applicable
func (r *testFooRun) Cancel(ctx context.Context) error {
	return r.client.CancelWorkflow(ctx, r.ID(), r.RunID())
}

// Get retrieves a test issue_125.v1.Issue125Service.Foo workflow result
func (r *testFooRun) Get(context.Context) (*FooOutput, error) {
	if r.isStarted.CompareAndSwap(false, true) {
		r.env.ExecuteWorkflow(FooWorkflowName, r.req)
	}
	if !r.env.IsWorkflowCompleted() {
		return nil, errors.New("workflow in progress")
	}
	if err := r.env.GetWorkflowError(); err != nil {
		return nil, err
	}
	var result FooOutput
	if err := r.env.GetWorkflowResult(&result); err != nil {
		return nil, err
	}
	return &result, nil
}

// ID returns a test issue_125.v1.Issue125Service.Foo workflow run's workflow ID
func (r *testFooRun) ID() string {
	if r.opts != nil {
		return r.opts.ID
	}
	return ""
}

// Run noop implementation
func (r *testFooRun) Run() client.WorkflowRun {
	return nil
}

// RunID noop implementation
func (r *testFooRun) RunID() string {
	return ""
}

// Terminate terminates a workflow in execution, returning an error if applicable
func (r *testFooRun) Terminate(ctx context.Context, reason string, details ...interface{}) error {
	return r.client.TerminateWorkflow(ctx, r.ID(), r.RunID(), reason, details...)
}

// Bar executes a(n) issue_125.v1.Issue125Service.Bar update against a test issue_125.v1.Issue125Service.Foo workflow
func (r *testFooRun) Bar(ctx context.Context, req *BarInput, opts ...*BarOptions) (*BarOutput, error) {
	return r.client.Bar(ctx, r.ID(), r.RunID(), req, opts...)
}

// BarAsync executes a(n) issue_125.v1.Issue125Service.Bar update against a test issue_125.v1.Issue125Service.Foo workflow
func (r *testFooRun) BarAsync(ctx context.Context, req *BarInput, opts ...*BarOptions) (BarHandle, error) {
	return r.client.BarAsync(ctx, r.ID(), r.RunID(), req, opts...)
}

// Baz executes a(n) issue_125.v1.Issue125Service.Baz update against a test issue_125.v1.Issue125Service.Foo workflow
func (r *testFooRun) Baz(ctx context.Context, req *BazInput, opts ...*BazOptions) (*BazOutput, error) {
	return r.client.Baz(ctx, r.ID(), r.RunID(), req, opts...)
}

// BazAsync executes a(n) issue_125.v1.Issue125Service.Baz update against a test issue_125.v1.Issue125Service.Foo workflow
func (r *testFooRun) BazAsync(ctx context.Context, req *BazInput, opts ...*BazOptions) (BazHandle, error) {
	return r.client.BazAsync(ctx, r.ID(), r.RunID(), req, opts...)
}

// Issue125ServiceCliOptions describes runtime configuration for issue_125.v1.Issue125Service cli
type Issue125ServiceCliOptions struct {
	after            func(*v2.Context) error
	before           func(*v2.Context) error
	clientForCommand func(*v2.Context) (client.Client, error)
	worker           func(*v2.Context, client.Client) (worker.Worker, error)
}

// NewIssue125ServiceCliOptions initializes a new Issue125ServiceCliOptions value
func NewIssue125ServiceCliOptions() *Issue125ServiceCliOptions {
	return &Issue125ServiceCliOptions{}
}

// WithAfter injects a custom After hook to be run after any command invocation
func (opts *Issue125ServiceCliOptions) WithAfter(fn func(*v2.Context) error) *Issue125ServiceCliOptions {
	opts.after = fn
	return opts
}

// WithBefore injects a custom Before hook to be run prior to any command invocation
func (opts *Issue125ServiceCliOptions) WithBefore(fn func(*v2.Context) error) *Issue125ServiceCliOptions {
	opts.before = fn
	return opts
}

// WithClient provides a Temporal client factory for use by commands
func (opts *Issue125ServiceCliOptions) WithClient(fn func(*v2.Context) (client.Client, error)) *Issue125ServiceCliOptions {
	opts.clientForCommand = fn
	return opts
}

// WithWorker provides an method for initializing a worker
func (opts *Issue125ServiceCliOptions) WithWorker(fn func(*v2.Context, client.Client) (worker.Worker, error)) *Issue125ServiceCliOptions {
	opts.worker = fn
	return opts
}

// NewIssue125ServiceCli initializes a cli for a(n) issue_125.v1.Issue125Service service
func NewIssue125ServiceCli(options ...*Issue125ServiceCliOptions) (*v2.App, error) {
	commands, err := newIssue125ServiceCommands(options...)
	if err != nil {
		return nil, fmt.Errorf("error initializing subcommands: %w", err)
	}
	return &v2.App{
		Name:                      "issue-125-service",
		Commands:                  commands,
		DisableSliceFlagSeparator: true,
	}, nil
}

// NewIssue125ServiceCliCommand initializes a cli command for a issue_125.v1.Issue125Service service with subcommands for each query, signal, update, and workflow
func NewIssue125ServiceCliCommand(options ...*Issue125ServiceCliOptions) (*v2.Command, error) {
	subcommands, err := newIssue125ServiceCommands(options...)
	if err != nil {
		return nil, fmt.Errorf("error initializing subcommands: %w", err)
	}
	return &v2.Command{
		Name:        "issue-125-service",
		Subcommands: subcommands,
	}, nil
}

// newIssue125ServiceCommands initializes (sub)commands for a issue_125.v1.Issue125Service cli or command
func newIssue125ServiceCommands(options ...*Issue125ServiceCliOptions) ([]*v2.Command, error) {
	opts := &Issue125ServiceCliOptions{}
	if len(options) > 0 {
		opts = options[0]
	}
	if opts.clientForCommand == nil {
		opts.clientForCommand = func(*v2.Context) (client.Client, error) {
			return client.Dial(client.Options{})
		}
	}
	commands := []*v2.Command{
		{
			Name:                   "bar",
			Usage:                  "executes a(n) issue_125.v1.Issue125Service.Bar update",
			Category:               "UPDATES",
			UseShortOptionHandling: true,
			Before:                 opts.before,
			After:                  opts.after,
			Flags: []v2.Flag{
				&v2.BoolFlag{
					Name:    "detach",
					Usage:   "run workflow update in the background and print workflow, execution, and udpate id",
					Aliases: []string{"d"},
				},
				&v2.StringFlag{
					Name:     "workflow-id",
					Usage:    "workflow id",
					Required: true,
					Aliases:  []string{"w"},
				},
				&v2.StringFlag{
					Name:    "run-id",
					Usage:   "run id",
					Aliases: []string{"r"},
				},
				&v2.StringFlag{
					Name:     "input-file",
					Usage:    "path to json-formatted input file",
					Aliases:  []string{"f"},
					Category: "INPUT",
				},
				&v2.StringFlag{
					Name:     "id",
					Usage:    "set the value of the operation's \"Id\" parameter",
					Category: "INPUT",
				},
			},
			Action: func(cmd *v2.Context) error {
				c, err := opts.clientForCommand(cmd)
				if err != nil {
					return fmt.Errorf("error initializing client for command: %w", err)
				}
				defer c.Close()
				client := NewIssue125ServiceClient(c)
				req, err := UnmarshalCliFlagsToBarInput(cmd, helpers.UnmarshalCliFlagsOptions{FromFile: "input-file"})
				if err != nil {
					return fmt.Errorf("error unmarshalling request: %w", err)
				}
				handle, err := client.BarAsync(cmd.Context, cmd.String("workflow-id"), cmd.String("run-id"), req)
				if err != nil {
					return fmt.Errorf("error executing %s update: %w", BarUpdateName, err)
				}
				if cmd.Bool("detach") {
					fmt.Println("success")
					fmt.Printf("workflow id: %s\n", handle.WorkflowID())
					fmt.Printf("run id: %s\n", handle.RunID())
					fmt.Printf("update id: %s\n", handle.UpdateID())
					return nil
				}
				if resp, err := handle.Get(cmd.Context); err != nil {
					return err
				} else {
					b, err := protojson.Marshal(resp)
					if err != nil {
						return fmt.Errorf("error serializing response json: %w", err)
					}
					var out bytes.Buffer
					if err := json.Indent(&out, b, "", "  "); err != nil {
						return fmt.Errorf("error formatting json: %w", err)
					}
					fmt.Println(out.String())
					return nil
				}
			},
		},
		{
			Name:                   "baz",
			Usage:                  "executes a(n) issue_125.v1.Issue125Service.Baz update",
			Category:               "UPDATES",
			UseShortOptionHandling: true,
			Before:                 opts.before,
			After:                  opts.after,
			Flags: []v2.Flag{
				&v2.BoolFlag{
					Name:    "detach",
					Usage:   "run workflow update in the background and print workflow, execution, and udpate id",
					Aliases: []string{"d"},
				},
				&v2.StringFlag{
					Name:     "workflow-id",
					Usage:    "workflow id",
					Required: true,
					Aliases:  []string{"w"},
				},
				&v2.StringFlag{
					Name:    "run-id",
					Usage:   "run id",
					Aliases: []string{"r"},
				},
				&v2.StringFlag{
					Name:     "input-file",
					Usage:    "path to json-formatted input file",
					Aliases:  []string{"f"},
					Category: "INPUT",
				},
				&v2.StringFlag{
					Name:     "id",
					Usage:    "set the value of the operation's \"Id\" parameter",
					Category: "INPUT",
				},
			},
			Action: func(cmd *v2.Context) error {
				c, err := opts.clientForCommand(cmd)
				if err != nil {
					return fmt.Errorf("error initializing client for command: %w", err)
				}
				defer c.Close()
				client := NewIssue125ServiceClient(c)
				req, err := UnmarshalCliFlagsToBazInput(cmd, helpers.UnmarshalCliFlagsOptions{FromFile: "input-file"})
				if err != nil {
					return fmt.Errorf("error unmarshalling request: %w", err)
				}
				handle, err := client.BazAsync(cmd.Context, cmd.String("workflow-id"), cmd.String("run-id"), req)
				if err != nil {
					return fmt.Errorf("error executing %s update: %w", BazUpdateName, err)
				}
				if cmd.Bool("detach") {
					fmt.Println("success")
					fmt.Printf("workflow id: %s\n", handle.WorkflowID())
					fmt.Printf("run id: %s\n", handle.RunID())
					fmt.Printf("update id: %s\n", handle.UpdateID())
					return nil
				}
				if resp, err := handle.Get(cmd.Context); err != nil {
					return err
				} else {
					b, err := protojson.Marshal(resp)
					if err != nil {
						return fmt.Errorf("error serializing response json: %w", err)
					}
					var out bytes.Buffer
					if err := json.Indent(&out, b, "", "  "); err != nil {
						return fmt.Errorf("error formatting json: %w", err)
					}
					fmt.Println(out.String())
					return nil
				}
			},
		},
		{
			Name:                   "foo",
			Usage:                  "executes a(n) issue_125.v1.Issue125Service.Foo workflow",
			Category:               "WORKFLOWS",
			UseShortOptionHandling: true,
			Before:                 opts.before,
			After:                  opts.after,
			Flags: []v2.Flag{
				&v2.BoolFlag{
					Name:    "detach",
					Usage:   "run workflow in the background and print workflow and execution id",
					Aliases: []string{"d"},
				},
				&v2.StringFlag{
					Name:    "task-queue",
					Usage:   "task queue name",
					Aliases: []string{"t"},
					EnvVars: []string{"TEMPORAL_TASK_QUEUE_NAME", "TEMPORAL_TASK_QUEUE", "TASK_QUEUE_NAME", "TASK_QUEUE"},
					Value:   "issue-125-v1",
				},
				&v2.StringFlag{
					Name:     "input-file",
					Usage:    "path to json-formatted input file",
					Aliases:  []string{"f"},
					Category: "INPUT",
				},
				&v2.StringFlag{
					Name:     "id",
					Usage:    "set the value of the operation's \"Id\" parameter",
					Category: "INPUT",
				},
			},
			Action: func(cmd *v2.Context) error {
				tc, err := opts.clientForCommand(cmd)
				if err != nil {
					return fmt.Errorf("error initializing client for command: %w", err)
				}
				defer tc.Close()
				c := NewIssue125ServiceClient(tc)
				req, err := UnmarshalCliFlagsToFooInput(cmd, helpers.UnmarshalCliFlagsOptions{FromFile: "input-file"})
				if err != nil {
					return fmt.Errorf("error unmarshalling request: %w", err)
				}
				opts := client.StartWorkflowOptions{}
				if tq := cmd.String("task-queue"); tq != "" {
					opts.TaskQueue = tq
				}
				run, err := c.FooAsync(cmd.Context, req, NewFooOptions().WithStartWorkflowOptions(opts))
				if err != nil {
					return fmt.Errorf("error starting %s workflow: %w", FooWorkflowName, err)
				}
				if cmd.Bool("detach") {
					fmt.Println("success")
					fmt.Printf("workflow id: %s\n", run.ID())
					fmt.Printf("run id: %s\n", run.RunID())
					return nil
				}
				if resp, err := run.Get(cmd.Context); err != nil {
					return err
				} else {
					b, err := protojson.Marshal(resp)
					if err != nil {
						return fmt.Errorf("error serializing response json: %w", err)
					}
					var out bytes.Buffer
					if err := json.Indent(&out, b, "", "  "); err != nil {
						return fmt.Errorf("error formatting json: %w", err)
					}
					fmt.Println(out.String())
					return nil
				}
			},
		},
	}
	if opts.worker != nil {
		commands = append(commands, []*v2.Command{
			{
				Name:                   "worker",
				Usage:                  "runs a issue_125.v1.Issue125Service worker process",
				UseShortOptionHandling: true,
				Before:                 opts.before,
				After:                  opts.after,
				Action: func(cmd *v2.Context) error {
					c, err := opts.clientForCommand(cmd)
					if err != nil {
						return fmt.Errorf("error initializing client for command: %w", err)
					}
					defer c.Close()
					w, err := opts.worker(cmd, c)
					if opts.worker != nil {
						if err != nil {
							return fmt.Errorf("error initializing worker: %w", err)
						}
					}
					if err := w.Start(); err != nil {
						return fmt.Errorf("error starting worker: %w", err)
					}
					defer w.Stop()
					<-cmd.Context.Done()
					return nil
				},
			},
		}...)
	}
	sort.Slice(commands, func(i, j int) bool {
		return commands[i].Name < commands[j].Name
	})
	return commands, nil
}

// UnmarshalCliFlagsToBarInput unmarshals a BarInput from command line flags
func UnmarshalCliFlagsToBarInput(cmd *v2.Context, options ...helpers.UnmarshalCliFlagsOptions) (*BarInput, error) {
	opts := helpers.FlattenUnmarshalCliFlagsOptions(options...)
	var result BarInput
	if opts.FromFile != "" && cmd.IsSet(opts.FromFile) {
		f, err := gohomedir.Expand(cmd.String(opts.FromFile))
		if err != nil {
			f = cmd.String(opts.FromFile)
		}
		b, err := os.ReadFile(f)
		if err != nil {
			return nil, fmt.Errorf("error reading %s: %w", opts.FromFile, err)
		}
		if err := protojson.Unmarshal(b, &result); err != nil {
			return nil, fmt.Errorf("error parsing %s json: %w", opts.FromFile, err)
		}
	}
	if flag := opts.FlagName("id"); cmd.IsSet(flag) {
		value := cmd.String(flag)
		result.Id = value
	}
	return &result, nil
}

// UnmarshalCliFlagsToBazInput unmarshals a BazInput from command line flags
func UnmarshalCliFlagsToBazInput(cmd *v2.Context, options ...helpers.UnmarshalCliFlagsOptions) (*BazInput, error) {
	opts := helpers.FlattenUnmarshalCliFlagsOptions(options...)
	var result BazInput
	if opts.FromFile != "" && cmd.IsSet(opts.FromFile) {
		f, err := gohomedir.Expand(cmd.String(opts.FromFile))
		if err != nil {
			f = cmd.String(opts.FromFile)
		}
		b, err := os.ReadFile(f)
		if err != nil {
			return nil, fmt.Errorf("error reading %s: %w", opts.FromFile, err)
		}
		if err := protojson.Unmarshal(b, &result); err != nil {
			return nil, fmt.Errorf("error parsing %s json: %w", opts.FromFile, err)
		}
	}
	if flag := opts.FlagName("id"); cmd.IsSet(flag) {
		value := cmd.String(flag)
		result.Id = value
	}
	return &result, nil
}

// UnmarshalCliFlagsToFooInput unmarshals a FooInput from command line flags
func UnmarshalCliFlagsToFooInput(cmd *v2.Context, options ...helpers.UnmarshalCliFlagsOptions) (*FooInput, error) {
	opts := helpers.FlattenUnmarshalCliFlagsOptions(options...)
	var result FooInput
	if opts.FromFile != "" && cmd.IsSet(opts.FromFile) {
		f, err := gohomedir.Expand(cmd.String(opts.FromFile))
		if err != nil {
			f = cmd.String(opts.FromFile)
		}
		b, err := os.ReadFile(f)
		if err != nil {
			return nil, fmt.Errorf("error reading %s: %w", opts.FromFile, err)
		}
		if err := protojson.Unmarshal(b, &result); err != nil {
			return nil, fmt.Errorf("error parsing %s json: %w", opts.FromFile, err)
		}
	}
	if flag := opts.FlagName("id"); cmd.IsSet(flag) {
		value := cmd.String(flag)
		result.Id = value
	}
	return &result, nil
}

// WithIssue125ServiceSchemeTypes registers all Issue125Service protobuf types with the given scheme
func WithIssue125ServiceSchemeTypes() scheme.Option {
	return func(s *scheme.Scheme) {
		s.RegisterType(File_test_issue_125_v1_issue_125_proto.Messages().ByName("BarInput"))
		s.RegisterType(File_test_issue_125_v1_issue_125_proto.Messages().ByName("BarOutput"))
		s.RegisterType(File_test_issue_125_v1_issue_125_proto.Messages().ByName("BazInput"))
		s.RegisterType(File_test_issue_125_v1_issue_125_proto.Messages().ByName("BazOutput"))
		s.RegisterType(File_test_issue_125_v1_issue_125_proto.Messages().ByName("FooInput"))
		s.RegisterType(File_test_issue_125_v1_issue_125_proto.Messages().ByName("FooOutput"))
	}
}
