// Copyright 2021 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 servicecontrol

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

	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"
	servicecontrolpb "google.golang.org/genproto/googleapis/api/servicecontrol/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/metadata"
)

var newServiceControllerClientHook clientHook

// ServiceControllerCallOptions contains the retry settings for each method of ServiceControllerClient.
type ServiceControllerCallOptions struct {
	Check  []gax.CallOption
	Report []gax.CallOption
}

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

func defaultServiceControllerCallOptions() *ServiceControllerCallOptions {
	return &ServiceControllerCallOptions{
		Check:  []gax.CallOption{},
		Report: []gax.CallOption{},
	}
}

// internalServiceControllerClient is an interface that defines the methods availaible from Service Control API.
type internalServiceControllerClient interface {
	Close() error
	setGoogleClientInfo(...string)
	Connection() *grpc.ClientConn
	Check(context.Context, *servicecontrolpb.CheckRequest, ...gax.CallOption) (*servicecontrolpb.CheckResponse, error)
	Report(context.Context, *servicecontrolpb.ReportRequest, ...gax.CallOption) (*servicecontrolpb.ReportResponse, error)
}

// ServiceControllerClient is a client for interacting with Service Control API.
// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
//
// Google Service Control API (at https://cloud.google.com/service-control/overview)
//
// Lets clients check and report operations against a managed
// service (at https://cloud.google.com/service-management/reference/rpc/google.api/servicemanagement.v1#google.api.servicemanagement.v1.ManagedService).
type ServiceControllerClient struct {
	// The internal transport-dependent client.
	internalClient internalServiceControllerClient

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

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

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

// Check checks whether an operation on a service should be allowed to proceed
// based on the configuration of the service and related policies. It must be
// called before the operation is executed.
//
// If feasible, the client should cache the check results and reuse them for
// 60 seconds. In case of any server errors, the client should rely on the
// cached results for much longer time to avoid outage.
// WARNING: There is general 60s delay for the configuration and policy
// propagation, therefore callers MUST NOT depend on the Check method having
// the latest policy information.
//
// NOTE: the CheckRequest has the size limit of 64KB.
//
// This method requires the servicemanagement.services.check permission
// on the specified service. For more information, see
// Cloud IAM (at https://cloud.google.com/iam).
func (c *ServiceControllerClient) Check(ctx context.Context, req *servicecontrolpb.CheckRequest, opts ...gax.CallOption) (*servicecontrolpb.CheckResponse, error) {
	return c.internalClient.Check(ctx, req, opts...)
}

// Report reports operation results to Google Service Control, such as logs and
// metrics. It should be called after an operation is completed.
//
// If feasible, the client should aggregate reporting data for up to 5
// seconds to reduce API traffic. Limiting aggregation to 5 seconds is to
// reduce data loss during client crashes. Clients should carefully choose
// the aggregation time window to avoid data loss risk more than 0.01%
// for business and compliance reasons.
//
// NOTE: the ReportRequest has the size limit (wire-format byte size) of
// 1MB.
//
// This method requires the servicemanagement.services.report permission
// on the specified service. For more information, see
// Google Cloud IAM (at https://cloud.google.com/iam).
func (c *ServiceControllerClient) Report(ctx context.Context, req *servicecontrolpb.ReportRequest, opts ...gax.CallOption) (*servicecontrolpb.ReportResponse, error) {
	return c.internalClient.Report(ctx, req, opts...)
}

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

	// The gRPC API client.
	serviceControllerClient servicecontrolpb.ServiceControllerClient

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

// NewServiceControllerClient creates a new service controller client based on gRPC.
// The returned client must be Closed when it is done being used to clean up its underlying connections.
//
// Google Service Control API (at https://cloud.google.com/service-control/overview)
//
// Lets clients check and report operations against a managed
// service (at https://cloud.google.com/service-management/reference/rpc/google.api/servicemanagement.v1#google.api.servicemanagement.v1.ManagedService).
func NewServiceControllerClient(ctx context.Context, opts ...option.ClientOption) (*ServiceControllerClient, error) {
	clientOpts := defaultServiceControllerGRPCClientOptions()
	if newServiceControllerClientHook != nil {
		hookOpts, err := newServiceControllerClientHook(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 := ServiceControllerClient{CallOptions: defaultServiceControllerCallOptions()}

	c := &serviceControllerGRPCClient{
		connPool:                connPool,
		disableDeadlines:        disableDeadlines,
		serviceControllerClient: servicecontrolpb.NewServiceControllerClient(connPool),
		CallOptions:             &client.CallOptions,
	}
	c.setGoogleClientInfo()

	client.internalClient = c

	return &client, nil
}

// Connection returns a connection to the API service.
//
// Deprecated.
func (c *serviceControllerGRPCClient) 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 *serviceControllerGRPCClient) setGoogleClientInfo(keyval ...string) {
	kv := append([]string{"gl-go", versionGo()}, keyval...)
	kv = append(kv, "gapic", versionClient, "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 *serviceControllerGRPCClient) Close() error {
	return c.connPool.Close()
}

func (c *serviceControllerGRPCClient) Check(ctx context.Context, req *servicecontrolpb.CheckRequest, opts ...gax.CallOption) (*servicecontrolpb.CheckResponse, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "service_name", url.QueryEscape(req.GetServiceName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append((*c.CallOptions).Check[0:len((*c.CallOptions).Check):len((*c.CallOptions).Check)], opts...)
	var resp *servicecontrolpb.CheckResponse
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.serviceControllerClient.Check(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

func (c *serviceControllerGRPCClient) Report(ctx context.Context, req *servicecontrolpb.ReportRequest, opts ...gax.CallOption) (*servicecontrolpb.ReportResponse, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "service_name", url.QueryEscape(req.GetServiceName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append((*c.CallOptions).Report[0:len((*c.CallOptions).Report):len((*c.CallOptions).Report)], opts...)
	var resp *servicecontrolpb.ReportResponse
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.serviceControllerClient.Report(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
