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

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"
	dataqnapb "google.golang.org/genproto/googleapis/cloud/dataqna/v1alpha"
	"google.golang.org/grpc"
	"google.golang.org/grpc/metadata"
)

var newAutoSuggestionClientHook clientHook

// AutoSuggestionCallOptions contains the retry settings for each method of AutoSuggestionClient.
type AutoSuggestionCallOptions struct {
	SuggestQueries []gax.CallOption
}

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

func defaultAutoSuggestionCallOptions() *AutoSuggestionCallOptions {
	return &AutoSuggestionCallOptions{
		SuggestQueries: []gax.CallOption{},
	}
}

// internalAutoSuggestionClient is an interface that defines the methods availaible from Data QnA API.
type internalAutoSuggestionClient interface {
	Close() error
	setGoogleClientInfo(...string)
	Connection() *grpc.ClientConn
	SuggestQueries(context.Context, *dataqnapb.SuggestQueriesRequest, ...gax.CallOption) (*dataqnapb.SuggestQueriesResponse, error)
}

// AutoSuggestionClient is a client for interacting with Data QnA API.
// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
//
// This stateless API provides automatic suggestions for natural language
// queries for the data sources in the provided project and location.
//
// The service provides a resourceless operation suggestQueries that can be
// called to get a list of suggestions for a given incomplete query and scope
// (or list of scopes) under which the query is to be interpreted.
//
// There are two types of suggestions, ENTITY for single entity suggestions
// and TEMPLATE for full sentences. By default, both types are returned.
//
// Example Request:
//
// The service will retrieve information based on the given scope(s) and give
// suggestions based on that (e.g. “top item” for “top it” if “item” is a known
// dimension for the provided scope).
type AutoSuggestionClient struct {
	// The internal transport-dependent client.
	internalClient internalAutoSuggestionClient

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

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

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

// SuggestQueries gets a list of suggestions based on a prefix string.
// AutoSuggestion tolerance should be less than 1 second.
func (c *AutoSuggestionClient) SuggestQueries(ctx context.Context, req *dataqnapb.SuggestQueriesRequest, opts ...gax.CallOption) (*dataqnapb.SuggestQueriesResponse, error) {
	return c.internalClient.SuggestQueries(ctx, req, opts...)
}

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

	// The gRPC API client.
	autoSuggestionClient dataqnapb.AutoSuggestionServiceClient

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

// NewAutoSuggestionClient creates a new auto suggestion service client based on gRPC.
// The returned client must be Closed when it is done being used to clean up its underlying connections.
//
// This stateless API provides automatic suggestions for natural language
// queries for the data sources in the provided project and location.
//
// The service provides a resourceless operation suggestQueries that can be
// called to get a list of suggestions for a given incomplete query and scope
// (or list of scopes) under which the query is to be interpreted.
//
// There are two types of suggestions, ENTITY for single entity suggestions
// and TEMPLATE for full sentences. By default, both types are returned.
//
// Example Request:
//
// The service will retrieve information based on the given scope(s) and give
// suggestions based on that (e.g. “top item” for “top it” if “item” is a known
// dimension for the provided scope).
func NewAutoSuggestionClient(ctx context.Context, opts ...option.ClientOption) (*AutoSuggestionClient, error) {
	clientOpts := defaultAutoSuggestionGRPCClientOptions()
	if newAutoSuggestionClientHook != nil {
		hookOpts, err := newAutoSuggestionClientHook(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 := AutoSuggestionClient{CallOptions: defaultAutoSuggestionCallOptions()}

	c := &autoSuggestionGRPCClient{
		connPool:             connPool,
		disableDeadlines:     disableDeadlines,
		autoSuggestionClient: dataqnapb.NewAutoSuggestionServiceClient(connPool),
		CallOptions:          &client.CallOptions,
	}
	c.setGoogleClientInfo()

	client.internalClient = c

	return &client, nil
}

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

func (c *autoSuggestionGRPCClient) SuggestQueries(ctx context.Context, req *dataqnapb.SuggestQueriesRequest, opts ...gax.CallOption) (*dataqnapb.SuggestQueriesResponse, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 2000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))

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