func sliceContains(haystack []string, needle string) bool {
	for _, s := range haystack {
		if s == needle {
			return true
		}
	}
	return false
}
sliceContains returns true if haystack contains needle.
package sdhook
import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"cloud.google.com/go/compute/metadata"
	"github.com/fluent/fluent-logger-golang/fluent"
	"github.com/kenshaw/jwt/gserviceaccount"
	"github.com/sirupsen/logrus"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	errorReporting "google.golang.org/api/clouderrorreporting/v1beta1"
	logging "google.golang.org/api/logging/v2"
)
type Option func(*Hook) error
func Levels(levels ...logrus.Level) Option {
	return func(h *Hook) error {
		h.levels = levels
		return nil
	}
}
func ProjectID(projectID string) Option {
	return func(h *Hook) error {
		h.projectID = projectID
		return nil
	}
}
func EntriesService(service *logging.EntriesService) Option {
	return func(h *Hook) error {
		h.service = service
		return nil
	}
}
func LoggingService(service *logging.Service) Option {
	return func(h *Hook) error {
		h.service = service.Entries
		return nil
	}
}
func ErrorService(errorService *errorReporting.Service) Option {
	return func(h *Hook) error {
		h.errorService = errorService
		return nil
	}
}
func HTTPClient(client *http.Client) Option {
	return func(h *Hook) error {
		l, err := logging.New(client)
		if err != nil {
			return err
		}
		e, err := errorReporting.New(client)
		if err != nil {
			return err
		}
		if err = ErrorService(e)(h); err != nil {
			return err
		}
		return LoggingService(l)(h)
	}
}
func MonitoredResource(resource *logging.MonitoredResource) Option {
	return func(h *Hook) error {
		h.resource = resource
		return nil
	}
}
func Resource(typ ResType, labels map[string]string) Option {
	return func(h *Hook) error {
		return MonitoredResource(&logging.MonitoredResource{
			Type:   string(typ),
			Labels: labels,
		})(h)
	}
}
func LogName(name string) Option {
	return func(h *Hook) error {
		if h.projectID == "" {
			h.logName = name
		} else {
			h.logName = fmt.Sprintf("projects/%s/logs/%s", h.projectID, name)
		}
		return nil
	}
}
func ErrorReportingLogName(name string) Option {
	return func(h *Hook) error {
		h.errorReportingLogName = name
		return nil
	}
}
func Labels(labels map[string]string) Option {
	return func(h *Hook) error {
		h.labels = labels
		return nil
	}
}
func PartialSuccess(enabled bool) Option {
	return func(h *Hook) error {
		h.partialSuccess = enabled
		return nil
	}
}
func ErrorReportingService(service string) Option {
	return func(h *Hook) error {
		h.errorReportingServiceName = service
		return nil
	}
}
func UseLoggingServiceForErrors(enabled bool) Option {
	return func(h *Hook) error {
		h.useLoggingServiceForErrors = enabled
		return nil
	}
}
var requiredScopes = []string{
	logging.CloudPlatformScope,
}
func GoogleServiceAccountCredentialsJSON(buf []byte) Option {
	return func(h *Hook) error {
		gsa, err := gserviceaccount.FromJSON(buf)
		if err != nil {
			return err
		}
		if gsa.ProjectID == "" {
			return errors.New("google service account credentials missing project_id")
		}
		if err = ProjectID(gsa.ProjectID)(h); err != nil {
			return err
		}
		err = Resource(ResTypeProject, map[string]string{
			"project_id": gsa.ProjectID,
		})(h)
		if err != nil {
			return err
		}
		ts, err := gsa.TokenSource(nil, requiredScopes...)
		if err != nil {
			return err
		}
		return HTTPClient(&http.Client{
			Transport: &oauth2.Transport{
				Source: oauth2.ReuseTokenSource(nil, ts),
			},
		})(h)
	}
}
func GoogleServiceAccountCredentialsFile(path string) Option {
	return func(h *Hook) error {
		buf, err := ioutil.ReadFile(path)
		if err != nil {
			return err
		}
		return GoogleServiceAccountCredentialsJSON(buf)(h)
	}
}
func GoogleComputeCredentials(serviceAccount string) Option {
	return func(h *Hook) error {
		scopes, err := metadata.Scopes(serviceAccount)
		if err != nil {
			return err
		}
		for _, s := range requiredScopes {
			if !sliceContains(scopes, s) {
				return fmt.Errorf("missing required scope %s in compute metadata", s)
			}
		}
		return HTTPClient(&http.Client{
			Transport: &oauth2.Transport{
				Source: google.ComputeTokenSource(serviceAccount),
			},
		})(h)
	}
}
func GoogleLoggingAgent() Option {
	return func(h *Hook) error {
		var err error
		h.agentClient, err = fluent.New(
			fluent.Config{
				Async: true,
			},
		)
		if err != nil {
			return fmt.Errorf("could not find fluentd agent on 127.0.0.1:24224: %v", err)
		}
		return nil
	}
}