// Code generated by Wire. DO NOT EDIT.

//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject

package main

import (
	"context"
	"database/sql"
	"fmt"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/container"
	"github.com/aws/aws-sdk-go-v2/service/s3"
	"github.com/aws/aws-sdk-go-v2/service/ssm"
	"github.com/go-sql-driver/mysql"
	"go.opentelemetry.io/otel/metric"
	"go.opentelemetry.io/otel/propagation"
	"go.opentelemetry.io/otel/trace"
	"gocloud.dev/aws"
	"gocloud.dev/aws/rds"
	"gocloud.dev/blob"
	"gocloud.dev/blob/azureblob"
	"gocloud.dev/blob/fileblob"
	"gocloud.dev/blob/gcsblob"
	"gocloud.dev/blob/s3blob"
	"gocloud.dev/gcp"
	"gocloud.dev/gcp/cloudsql"
	"gocloud.dev/mysql/awsmysql"
	"gocloud.dev/mysql/gcpmysql"
	"gocloud.dev/runtimevar"
	"gocloud.dev/runtimevar/awsparamstore"
	"gocloud.dev/runtimevar/blobvar"
	"gocloud.dev/runtimevar/filevar"
	"gocloud.dev/runtimevar/gcpruntimeconfig"
	"gocloud.dev/server"
	"gocloud.dev/server/requestlog"
	"gocloud.dev/server/sdserver"
	"gocloud.dev/server/xrayserver"
	"google.golang.org/genproto/googleapis/cloud/runtimeconfig/v1beta1"
	"net/http"
	"net/url"
)

// Injectors from inject_aws.go:

// setupAWS is a Wire injector function that sets up the application using AWS.
func setupAWS(ctx context.Context, flags *cliFlags) (*server.Server, func(), error) {
	client := _wireClientValue
	certFetcher := &rds.CertFetcher{
		Client: client,
	}
	urlOpener := &awsmysql.URLOpener{
		CertSource: certFetcher,
	}
	db, cleanup, err := openAWSDatabase(ctx, urlOpener, flags)
	if err != nil {
		return nil, nil, err
	}
	config, err := aws.NewDefaultV2Config(ctx)
	if err != nil {
		cleanup()
		return nil, nil, err
	}
	s3Client := s3blob.Dial(config)
	bucket, cleanup2, err := awsBucket(ctx, s3Client, flags)
	if err != nil {
		cleanup()
		return nil, nil, err
	}
	ssmClient := awsparamstore.Dial(config)
	variable, err := awsMOTDVar(ctx, ssmClient, flags)
	if err != nil {
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	mainApplication := newApplication(db, bucket, variable)
	router := newRouter(mainApplication)
	ncsaLogger := xrayserver.NewRequestLogger()
	v, cleanup3 := appHealthChecks(db)
	propagator := xrayserver.NewTextMapPropagator()
	spanExporter, err := xrayserver.NewTraceExporter(ctx)
	if err != nil {
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	sampler := xrayserver.NewTraceSampler()
	tracerProvider, cleanup4, err := xrayserver.NewTraceProvider(ctx, spanExporter, sampler)
	if err != nil {
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	reader, err := xrayserver.NewMetricsReader(ctx)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	meterProvider, cleanup5, err := xrayserver.NewMeterProvider(ctx, reader)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	defaultDriver := _wireDefaultDriverValue
	options := &server.Options{
		RequestLogger:          ncsaLogger,
		HealthChecks:           v,
		TraceTextMapPropagator: propagator,
		TraceProvider:          tracerProvider,
		MetricsProvider:        meterProvider,
		Driver:                 defaultDriver,
	}
	serverServer := server.New(router, options)
	return serverServer, func() {
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
	}, nil
}

var (
	_wireClientValue        = http.DefaultClient
	_wireDefaultDriverValue = &server.DefaultDriver{}
)

// Injectors from inject_azure.go:

// setupAzure is a Wire injector function that sets up the application using
// Azure.
func setupAzure(ctx context.Context, flags *cliFlags) (*server.Server, func(), error) {
	db, err := dialLocalSQL(flags)
	if err != nil {
		return nil, nil, err
	}
	serviceURLOptions := azureblob.NewDefaultServiceURLOptions()
	serviceURL, err := azureblob.NewServiceURL(serviceURLOptions)
	if err != nil {
		return nil, nil, err
	}
	containerName := bucketName(flags)
	client, err := azureblob.NewDefaultClient(serviceURL, containerName)
	if err != nil {
		return nil, nil, err
	}
	bucket, cleanup, err := azureBucket(ctx, client, flags)
	if err != nil {
		return nil, nil, err
	}
	variable, err := azureMOTDVar(ctx, bucket, flags)
	if err != nil {
		cleanup()
		return nil, nil, err
	}
	mainApplication := newApplication(db, bucket, variable)
	router := newRouter(mainApplication)
	logger := _wireLoggerValue
	v, cleanup2 := appHealthChecks(db)
	textMapPropagator := _wireTextMapPropagatorValue
	tracerProvider := _wireTracerProviderValue
	meterProvider := _wireMeterProviderValue
	defaultDriver := _wireDefaultDriverValue
	options := &server.Options{
		RequestLogger:          logger,
		HealthChecks:           v,
		TraceTextMapPropagator: textMapPropagator,
		TraceProvider:          tracerProvider,
		MetricsProvider:        meterProvider,
		Driver:                 defaultDriver,
	}
	serverServer := server.New(router, options)
	return serverServer, func() {
		cleanup2()
		cleanup()
	}, nil
}

var (
	_wireLoggerValue            = requestlog.Logger(nil)
	_wireTextMapPropagatorValue = propagation.TextMapPropagator(nil)
	_wireTracerProviderValue    = trace.TracerProvider(nil)
	_wireMeterProviderValue     = metric.MeterProvider(nil)
)

// Injectors from inject_gcp.go:

// setupGCP is a Wire injector function that sets up the application using GCP.
func setupGCP(ctx context.Context, flags *cliFlags) (*server.Server, func(), error) {
	roundTripper := gcp.DefaultTransport()
	credentials, err := gcp.DefaultCredentials(ctx)
	if err != nil {
		return nil, nil, err
	}
	tokenSource := gcp.CredentialsTokenSource(credentials)
	httpClient, err := gcp.NewHTTPClient(roundTripper, tokenSource)
	if err != nil {
		return nil, nil, err
	}
	remoteCertSource := cloudsql.NewCertSource(httpClient)
	urlOpener := &gcpmysql.URLOpener{
		CertSource: remoteCertSource,
	}
	projectID, err := gcp.DefaultProjectID(credentials)
	if err != nil {
		return nil, nil, err
	}
	db, cleanup, err := openGCPDatabase(ctx, urlOpener, projectID, flags)
	if err != nil {
		return nil, nil, err
	}
	bucket, cleanup2, err := gcpBucket(ctx, flags, httpClient)
	if err != nil {
		cleanup()
		return nil, nil, err
	}
	runtimeConfigManagerClient, cleanup3, err := gcpruntimeconfig.Dial(ctx, tokenSource)
	if err != nil {
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	variable, cleanup4, err := gcpMOTDVar(ctx, runtimeConfigManagerClient, projectID, flags)
	if err != nil {
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	mainApplication := newApplication(db, bucket, variable)
	router := newRouter(mainApplication)
	stackdriverLogger := sdserver.NewRequestLogger()
	v, cleanup5 := appHealthChecks(db)
	textMapPropagator := sdserver.NewTextMapPropagator()
	spanExporter, err := sdserver.NewTraceExporter(projectID)
	if err != nil {
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	sampler := sdserver.NewTraceSampler(ctx)
	tracerProvider, cleanup6, err := sdserver.NewTraceProvider(ctx, spanExporter, sampler)
	if err != nil {
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	reader, err := sdserver.NewMetricsReader(projectID)
	if err != nil {
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	meterProvider, cleanup7, err := sdserver.NewMeterProvider(ctx, reader)
	if err != nil {
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	defaultDriver := _wireDefaultDriverValue
	options := &server.Options{
		RequestLogger:          stackdriverLogger,
		HealthChecks:           v,
		TraceTextMapPropagator: textMapPropagator,
		TraceProvider:          tracerProvider,
		MetricsProvider:        meterProvider,
		Driver:                 defaultDriver,
	}
	serverServer := server.New(router, options)
	return serverServer, func() {
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
	}, nil
}

// Injectors from inject_local.go:

// setupLocal is a Wire injector function that sets up the application using
// local implementations.
func setupLocal(ctx context.Context, flags *cliFlags) (*server.Server, func(), error) {
	db, err := dialLocalSQL(flags)
	if err != nil {
		return nil, nil, err
	}
	bucket, err := localBucket(flags)
	if err != nil {
		return nil, nil, err
	}
	variable, cleanup, err := localRuntimeVar(flags)
	if err != nil {
		return nil, nil, err
	}
	mainApplication := newApplication(db, bucket, variable)
	router := newRouter(mainApplication)
	logger := _wireRequestlogLoggerValue
	v, cleanup2 := appHealthChecks(db)
	textMapPropagator := newPropagationTextMap()
	spanExporter, err := newTraceExporter(ctx)
	if err != nil {
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	sampler := newTraceSampler(ctx)
	tracerProvider, cleanup3 := NewTraceProvider(ctx, spanExporter, sampler)
	reader, err := newMetricsReader(ctx)
	if err != nil {
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	meterProvider, cleanup4 := NewMeterProvider(ctx, reader)
	defaultDriver := _wireDefaultDriverValue
	options := &server.Options{
		RequestLogger:          logger,
		HealthChecks:           v,
		TraceTextMapPropagator: textMapPropagator,
		TraceProvider:          tracerProvider,
		MetricsProvider:        meterProvider,
		Driver:                 defaultDriver,
	}
	serverServer := server.New(router, options)
	return serverServer, func() {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
	}, nil
}

var (
	_wireRequestlogLoggerValue = requestlog.Logger(nil)
)

// inject_aws.go:

// awsBucket is a Wire provider function that returns the S3 bucket based on the
// command-line flags.
func awsBucket(ctx context.Context, client *s3.Client, flags *cliFlags) (*blob.Bucket, func(), error) {
	b, err := s3blob.OpenBucketV2(ctx, client, flags.bucket, nil)
	if err != nil {
		return nil, nil, err
	}
	return b, func() { b.Close() }, nil
}

// openAWSDatabase is a Wire provider function that connects to an AWS RDS
// MySQL database based on the command-line flags.
func openAWSDatabase(ctx context.Context, opener *awsmysql.URLOpener, flags *cliFlags) (*sql.DB, func(), error) {
	db, err := opener.OpenMySQLURL(ctx, &url.URL{
		Scheme: "awsmysql",
		User:   url.UserPassword(flags.dbUser, flags.dbPassword),
		Host:   flags.dbHost,
		Path:   "/" + flags.dbName,
	})
	if err != nil {
		return nil, nil, err
	}
	return db, func() { db.Close() }, nil
}

// awsMOTDVar is a Wire provider function that returns the Message of the Day
// variable from SSM Parameter Store.
func awsMOTDVar(ctx context.Context, client *ssm.Client, flags *cliFlags) (*runtimevar.Variable, error) {
	return awsparamstore.OpenVariableV2(client, flags.motdVar, runtimevar.StringDecoder, &awsparamstore.Options{
		WaitDuration: flags.motdVarWaitTime,
	})
}

// inject_azure.go:

func bucketName(flags *cliFlags) azureblob.ContainerName {
	return azureblob.ContainerName(flags.bucket)
}

// azureBucket is a Wire provider function that returns the Azure bucket based
// on the command-line flags.
func azureBucket(ctx context.Context, client *container.Client, flags *cliFlags) (*blob.Bucket, func(), error) {
	b, err := azureblob.OpenBucket(ctx, client, nil)
	if err != nil {
		return nil, nil, err
	}
	return b, func() { b.Close() }, nil
}

// azureMOTDVar is a Wire provider function that returns the Message of the Day
// variable read from a blob stored in Azure.
func azureMOTDVar(ctx context.Context, b *blob.Bucket, flags *cliFlags) (*runtimevar.Variable, error) {
	return blobvar.OpenVariable(b, flags.motdVar, runtimevar.StringDecoder, &blobvar.Options{
		WaitDuration: flags.motdVarWaitTime,
	})
}

// inject_gcp.go:

// gcpBucket is a Wire provider function that returns the GCS bucket based on
// the command-line flags.
func gcpBucket(ctx context.Context, flags *cliFlags, client *gcp.HTTPClient) (*blob.Bucket, func(), error) {
	b, err := gcsblob.OpenBucket(ctx, client, flags.bucket, nil)
	if err != nil {
		return nil, nil, err
	}
	return b, func() { b.Close() }, nil
}

// openGCPDatabase is a Wire provider function that connects to a GCP Cloud SQL
// MySQL database based on the command-line flags.
func openGCPDatabase(ctx context.Context, opener *gcpmysql.URLOpener, id gcp.ProjectID, flags *cliFlags) (*sql.DB, func(), error) {
	db, err := opener.OpenMySQLURL(ctx, &url.URL{
		Scheme: "gcpmysql",
		User:   url.UserPassword(flags.dbUser, flags.dbPassword),
		Host:   string(id),
		Path:   fmt.Sprintf("/%s/%s/%s", flags.cloudSQLRegion, flags.dbHost, flags.dbName),
	})
	if err != nil {
		return nil, nil, err
	}
	return db, func() { db.Close() }, nil
}

// gcpMOTDVar is a Wire provider function that returns the Message of the Day
// variable from Runtime Configurator.
func gcpMOTDVar(ctx context.Context, client runtimeconfig.RuntimeConfigManagerClient, project gcp.ProjectID, flags *cliFlags) (*runtimevar.Variable, func(), error) {
	variableKey := gcpruntimeconfig.VariableKey(project, flags.runtimeConfigName, flags.motdVar)
	v, err := gcpruntimeconfig.OpenVariable(client, variableKey, runtimevar.StringDecoder, &gcpruntimeconfig.Options{
		WaitDuration: flags.motdVarWaitTime,
	})
	if err != nil {
		return nil, nil, err
	}
	return v, func() { v.Close() }, nil
}

// inject_local.go:

// localBucket is a Wire provider function that returns a directory-based bucket
// based on the command-line flags.
func localBucket(flags *cliFlags) (*blob.Bucket, error) {
	return fileblob.OpenBucket(flags.bucket, nil)
}

// dialLocalSQL is a Wire provider function that connects to a MySQL database
// (usually on localhost).
func dialLocalSQL(flags *cliFlags) (*sql.DB, error) {
	cfg := &mysql.Config{
		Net:                  "tcp",
		Addr:                 flags.dbHost,
		DBName:               flags.dbName,
		User:                 flags.dbUser,
		Passwd:               flags.dbPassword,
		AllowNativePasswords: true,
	}
	return sql.Open("mysql", cfg.FormatDSN())
}

// localRuntimeVar is a Wire provider function that returns the Message of the
// Day variable based on a local file.
func localRuntimeVar(flags *cliFlags) (*runtimevar.Variable, func(), error) {
	v, err := filevar.OpenVariable(flags.motdVar, runtimevar.StringDecoder, &filevar.Options{
		WaitDuration: flags.motdVarWaitTime,
	})
	if err != nil {
		return nil, nil, err
	}
	return v, func() { v.Close() }, nil
}
