// 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
	PublishEvents                  []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{},
		PublishEvents:                  []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)
	PublishEvents(context.Context, *publisherpb.PublishEventsRequest, ...gax.CallOption) (*publisherpb.PublishEventsResponse, 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...)
}

// PublishEvents publish events to a subscriber’s channel.
func (c *PublisherClient) PublishEvents(ctx context.Context, req *publisherpb.PublishEventsRequest, opts ...gax.CallOption) (*publisherpb.PublishEventsResponse, error) {
	return c.internalClient.PublishEvents(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
}

func (c *publisherGRPCClient) PublishEvents(ctx context.Context, req *publisherpb.PublishEventsRequest, opts ...gax.CallOption) (*publisherpb.PublishEventsResponse, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "channel", url.QueryEscape(req.GetChannel())))

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