// 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 gateway

import (
	"context"
	"math"

	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"
	httpbodypb "google.golang.org/genproto/googleapis/api/httpbody"
	gatewaypb "google.golang.org/genproto/googleapis/cloud/gkeconnect/gateway/v1beta1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/metadata"
)

var newClientHook clientHook

// CallOptions contains the retry settings for each method of Client.
type CallOptions struct {
	GetResource    []gax.CallOption
	PostResource   []gax.CallOption
	DeleteResource []gax.CallOption
	PutResource    []gax.CallOption
	PatchResource  []gax.CallOption
}

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

func defaultCallOptions() *CallOptions {
	return &CallOptions{
		GetResource:    []gax.CallOption{},
		PostResource:   []gax.CallOption{},
		DeleteResource: []gax.CallOption{},
		PutResource:    []gax.CallOption{},
		PatchResource:  []gax.CallOption{},
	}
}

// internalClient is an interface that defines the methods availaible from Connect Gateway API.
type internalClient interface {
	Close() error
	setGoogleClientInfo(...string)
	Connection() *grpc.ClientConn
	GetResource(context.Context, *httpbodypb.HttpBody, ...gax.CallOption) (*httpbodypb.HttpBody, error)
	PostResource(context.Context, *httpbodypb.HttpBody, ...gax.CallOption) (*httpbodypb.HttpBody, error)
	DeleteResource(context.Context, *httpbodypb.HttpBody, ...gax.CallOption) (*httpbodypb.HttpBody, error)
	PutResource(context.Context, *httpbodypb.HttpBody, ...gax.CallOption) (*httpbodypb.HttpBody, error)
	PatchResource(context.Context, *httpbodypb.HttpBody, ...gax.CallOption) (*httpbodypb.HttpBody, error)
}

// Client is a client for interacting with Connect Gateway API.
// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
//
// Gateway service is a public API which works as a Kubernetes resource model
// proxy between end users and registered Kubernetes clusters. Each RPC in this
// service matches with an HTTP verb. End user will initiate kubectl commands
// against the Gateway service, and Gateway service will forward user requests
// to clusters.
type Client struct {
	// The internal transport-dependent client.
	internalClient internalClient

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

// 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 *Client) 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 *Client) setGoogleClientInfo(keyval ...string) {
	c.internalClient.setGoogleClientInfo(keyval...)
}

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

// GetResource getResource performs an HTTP GET request on the Kubernetes API Server.
func (c *Client) GetResource(ctx context.Context, req *httpbodypb.HttpBody, opts ...gax.CallOption) (*httpbodypb.HttpBody, error) {
	return c.internalClient.GetResource(ctx, req, opts...)
}

// PostResource postResource performs an HTTP POST on the Kubernetes API Server.
func (c *Client) PostResource(ctx context.Context, req *httpbodypb.HttpBody, opts ...gax.CallOption) (*httpbodypb.HttpBody, error) {
	return c.internalClient.PostResource(ctx, req, opts...)
}

// DeleteResource deleteResource performs an HTTP DELETE on the Kubernetes API Server.
func (c *Client) DeleteResource(ctx context.Context, req *httpbodypb.HttpBody, opts ...gax.CallOption) (*httpbodypb.HttpBody, error) {
	return c.internalClient.DeleteResource(ctx, req, opts...)
}

// PutResource putResource performs an HTTP PUT on the Kubernetes API Server.
func (c *Client) PutResource(ctx context.Context, req *httpbodypb.HttpBody, opts ...gax.CallOption) (*httpbodypb.HttpBody, error) {
	return c.internalClient.PutResource(ctx, req, opts...)
}

// PatchResource patchResource performs an HTTP PATCH on the Kubernetes API Server.
func (c *Client) PatchResource(ctx context.Context, req *httpbodypb.HttpBody, opts ...gax.CallOption) (*httpbodypb.HttpBody, error) {
	return c.internalClient.PatchResource(ctx, req, opts...)
}

// gRPCClient is a client for interacting with Connect Gateway API over gRPC transport.
//
// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
type gRPCClient 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 Client
	CallOptions **CallOptions

	// The gRPC API client.
	client gatewaypb.GatewayServiceClient

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

// NewClient creates a new gateway service client based on gRPC.
// The returned client must be Closed when it is done being used to clean up its underlying connections.
//
// Gateway service is a public API which works as a Kubernetes resource model
// proxy between end users and registered Kubernetes clusters. Each RPC in this
// service matches with an HTTP verb. End user will initiate kubectl commands
// against the Gateway service, and Gateway service will forward user requests
// to clusters.
func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) {
	clientOpts := defaultGRPCClientOptions()
	if newClientHook != nil {
		hookOpts, err := newClientHook(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 := Client{CallOptions: defaultCallOptions()}

	c := &gRPCClient{
		connPool:         connPool,
		disableDeadlines: disableDeadlines,
		client:           gatewaypb.NewGatewayServiceClient(connPool),
		CallOptions:      &client.CallOptions,
	}
	c.setGoogleClientInfo()

	client.internalClient = c

	return &client, nil
}

// Connection returns a connection to the API service.
//
// Deprecated.
func (c *gRPCClient) 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 *gRPCClient) 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 *gRPCClient) Close() error {
	return c.connPool.Close()
}

func (c *gRPCClient) GetResource(ctx context.Context, req *httpbodypb.HttpBody, opts ...gax.CallOption) (*httpbodypb.HttpBody, error) {
	ctx = insertMetadata(ctx, c.xGoogMetadata)
	opts = append((*c.CallOptions).GetResource[0:len((*c.CallOptions).GetResource):len((*c.CallOptions).GetResource)], opts...)
	var resp *httpbodypb.HttpBody
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.client.GetResource(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

func (c *gRPCClient) PostResource(ctx context.Context, req *httpbodypb.HttpBody, opts ...gax.CallOption) (*httpbodypb.HttpBody, error) {
	ctx = insertMetadata(ctx, c.xGoogMetadata)
	opts = append((*c.CallOptions).PostResource[0:len((*c.CallOptions).PostResource):len((*c.CallOptions).PostResource)], opts...)
	var resp *httpbodypb.HttpBody
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.client.PostResource(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

func (c *gRPCClient) DeleteResource(ctx context.Context, req *httpbodypb.HttpBody, opts ...gax.CallOption) (*httpbodypb.HttpBody, error) {
	ctx = insertMetadata(ctx, c.xGoogMetadata)
	opts = append((*c.CallOptions).DeleteResource[0:len((*c.CallOptions).DeleteResource):len((*c.CallOptions).DeleteResource)], opts...)
	var resp *httpbodypb.HttpBody
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.client.DeleteResource(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

func (c *gRPCClient) PutResource(ctx context.Context, req *httpbodypb.HttpBody, opts ...gax.CallOption) (*httpbodypb.HttpBody, error) {
	ctx = insertMetadata(ctx, c.xGoogMetadata)
	opts = append((*c.CallOptions).PutResource[0:len((*c.CallOptions).PutResource):len((*c.CallOptions).PutResource)], opts...)
	var resp *httpbodypb.HttpBody
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.client.PutResource(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

func (c *gRPCClient) PatchResource(ctx context.Context, req *httpbodypb.HttpBody, opts ...gax.CallOption) (*httpbodypb.HttpBody, error) {
	ctx = insertMetadata(ctx, c.xGoogMetadata)
	opts = append((*c.CallOptions).PatchResource[0:len((*c.CallOptions).PatchResource):len((*c.CallOptions).PatchResource)], opts...)
	var resp *httpbodypb.HttpBody
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.client.PatchResource(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
