// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Code generated by protoc-gen-go_gapic. DO NOT EDIT.

package publishing

import (
	"context"
	"fmt"
	"math"
	"net/url"
	"time"

	gax "github.com/googleapis/gax-go/v2"
	"google.golang.org/api/option"
	"google.golang.org/api/option/internaloption"
	gtransport "google.golang.org/api/transport/grpc"
	publisherpb "google.golang.org/genproto/googleapis/cloud/eventarc/publishing/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/metadata"
)

var newPublisherClientHook clientHook

// PublisherCallOptions contains the retry settings for each method of PublisherClient.
type PublisherCallOptions struct {
	PublishChannelConnectionEvents []gax.CallOption
}

func defaultPublisherGRPCClientOptions() []option.ClientOption {
	return []option.ClientOption{
		internaloption.WithDefaultEndpoint("eventarcpublishing.googleapis.com:443"),
		internaloption.WithDefaultMTLSEndpoint("eventarcpublishing.mtls.googleapis.com:443"),
		internaloption.WithDefaultAudience("https://eventarcpublishing.googleapis.com/"),
		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
		internaloption.EnableJwtWithScope(),
		option.WithGRPCDialOption(grpc.WithDefaultCallOptions(
			grpc.MaxCallRecvMsgSize(math.MaxInt32))),
	}
}

func defaultPublisherCallOptions() *PublisherCallOptions {
	return &PublisherCallOptions{
		PublishChannelConnectionEvents: []gax.CallOption{},
	}
}

// internalPublisherClient is an interface that defines the methods availaible from Eventarc Publishing API.
type internalPublisherClient interface {
	Close() error
	setGoogleClientInfo(...string)
	Connection() *grpc.ClientConn
	PublishChannelConnectionEvents(context.Context, *publisherpb.PublishChannelConnectionEventsRequest, ...gax.CallOption) (*publisherpb.PublishChannelConnectionEventsResponse, error)
}

// PublisherClient is a client for interacting with Eventarc Publishing API.
// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
//
// Eventarc processes events generated by an event provider and delivers them to
// a subscriber.
//
// An event provider is a software-as-a-service (SaaS) system or
// product that can generate and deliver events through Eventarc.
//
// A third-party event provider is an event provider from outside of Google.
//
// A partner is a third-party event provider that is integrated with Eventarc.
//
// A subscriber is a GCP customer interested in receiving events.
//
// Channel is a first-class Eventarc resource that is created and managed
// by the subscriber in their GCP project. A Channel represents a subscriber’s
// intent to receive events from an event provider. A Channel is associated with
// exactly one event provider.
//
// ChannelConnection is a first-class Eventarc resource that
// is created and managed by the partner in their GCP project. A
// ChannelConnection represents a connection between a partner and a
// subscriber’s Channel. A ChannelConnection has a one-to-one mapping with a
// Channel.
//
// Publisher allows an event provider to publish events to Eventarc.
type PublisherClient struct {
	// The internal transport-dependent client.
	internalClient internalPublisherClient

	// The call options for this service.
	CallOptions *PublisherCallOptions
}

// Wrapper methods routed to the internal client.

// Close closes the connection to the API service. The user should invoke this when
// the client is no longer required.
func (c *PublisherClient) Close() error {
	return c.internalClient.Close()
}

// setGoogleClientInfo sets the name and version of the application in
// the `x-goog-api-client` header passed on each request. Intended for
// use by Google-written clients.
func (c *PublisherClient) setGoogleClientInfo(keyval ...string) {
	c.internalClient.setGoogleClientInfo(keyval...)
}

// Connection returns a connection to the API service.
//
// Deprecated.
func (c *PublisherClient) Connection() *grpc.ClientConn {
	return c.internalClient.Connection()
}

// PublishChannelConnectionEvents publish events to a ChannelConnection in a partner’s project.
func (c *PublisherClient) PublishChannelConnectionEvents(ctx context.Context, req *publisherpb.PublishChannelConnectionEventsRequest, opts ...gax.CallOption) (*publisherpb.PublishChannelConnectionEventsResponse, error) {
	return c.internalClient.PublishChannelConnectionEvents(ctx, req, opts...)
}

// publisherGRPCClient is a client for interacting with Eventarc Publishing API over gRPC transport.
//
// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
type publisherGRPCClient struct {
	// Connection pool of gRPC connections to the service.
	connPool gtransport.ConnPool

	// flag to opt out of default deadlines via GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE
	disableDeadlines bool

	// Points back to the CallOptions field of the containing PublisherClient
	CallOptions **PublisherCallOptions

	// The gRPC API client.
	publisherClient publisherpb.PublisherClient

	// The x-goog-* metadata to be sent with each request.
	xGoogMetadata metadata.MD
}

// NewPublisherClient creates a new publisher client based on gRPC.
// The returned client must be Closed when it is done being used to clean up its underlying connections.
//
// Eventarc processes events generated by an event provider and delivers them to
// a subscriber.
//
// An event provider is a software-as-a-service (SaaS) system or
// product that can generate and deliver events through Eventarc.
//
// A third-party event provider is an event provider from outside of Google.
//
// A partner is a third-party event provider that is integrated with Eventarc.
//
// A subscriber is a GCP customer interested in receiving events.
//
// Channel is a first-class Eventarc resource that is created and managed
// by the subscriber in their GCP project. A Channel represents a subscriber’s
// intent to receive events from an event provider. A Channel is associated with
// exactly one event provider.
//
// ChannelConnection is a first-class Eventarc resource that
// is created and managed by the partner in their GCP project. A
// ChannelConnection represents a connection between a partner and a
// subscriber’s Channel. A ChannelConnection has a one-to-one mapping with a
// Channel.
//
// Publisher allows an event provider to publish events to Eventarc.
func NewPublisherClient(ctx context.Context, opts ...option.ClientOption) (*PublisherClient, error) {
	clientOpts := defaultPublisherGRPCClientOptions()
	if newPublisherClientHook != nil {
		hookOpts, err := newPublisherClientHook(ctx, clientHookParams{})
		if err != nil {
			return nil, err
		}
		clientOpts = append(clientOpts, hookOpts...)
	}

	disableDeadlines, err := checkDisableDeadlines()
	if err != nil {
		return nil, err
	}

	connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...)
	if err != nil {
		return nil, err
	}
	client := PublisherClient{CallOptions: defaultPublisherCallOptions()}

	c := &publisherGRPCClient{
		connPool:         connPool,
		disableDeadlines: disableDeadlines,
		publisherClient:  publisherpb.NewPublisherClient(connPool),
		CallOptions:      &client.CallOptions,
	}
	c.setGoogleClientInfo()

	client.internalClient = c

	return &client, nil
}

// Connection returns a connection to the API service.
//
// Deprecated.
func (c *publisherGRPCClient) Connection() *grpc.ClientConn {
	return c.connPool.Conn()
}

// setGoogleClientInfo sets the name and version of the application in
// the `x-goog-api-client` header passed on each request. Intended for
// use by Google-written clients.
func (c *publisherGRPCClient) setGoogleClientInfo(keyval ...string) {
	kv := append([]string{"gl-go", versionGo()}, keyval...)
	kv = append(kv, "gapic", getVersionClient(), "gax", gax.Version, "grpc", grpc.Version)
	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
}

// Close closes the connection to the API service. The user should invoke this when
// the client is no longer required.
func (c *publisherGRPCClient) Close() error {
	return c.connPool.Close()
}

func (c *publisherGRPCClient) PublishChannelConnectionEvents(ctx context.Context, req *publisherpb.PublishChannelConnectionEventsRequest, opts ...gax.CallOption) (*publisherpb.PublishChannelConnectionEventsResponse, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "channel_connection", url.QueryEscape(req.GetChannelConnection())))

	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append((*c.CallOptions).PublishChannelConnectionEvents[0:len((*c.CallOptions).PublishChannelConnectionEvents):len((*c.CallOptions).PublishChannelConnectionEvents)], opts...)
	var resp *publisherpb.PublishChannelConnectionEventsResponse
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.publisherClient.PublishChannelConnectionEvents(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
