// Code generated by mockery v0.0.0-dev. DO NOT EDIT.

package mocks

import (
	context "context"

	iam "cloud.google.com/go/iam"
	gopubsub "go.skia.org/infra/go/pubsub"

	mock "github.com/stretchr/testify/mock"

	pubsub "cloud.google.com/go/pubsub"
)

// Topic is an autogenerated mock type for the Topic type
type Topic struct {
	mock.Mock
}

// Config provides a mock function with given fields: ctx
func (_m *Topic) Config(ctx context.Context) (pubsub.TopicConfig, error) {
	ret := _m.Called(ctx)

	if len(ret) == 0 {
		panic("no return value specified for Config")
	}

	var r0 pubsub.TopicConfig
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context) (pubsub.TopicConfig, error)); ok {
		return rf(ctx)
	}
	if rf, ok := ret.Get(0).(func(context.Context) pubsub.TopicConfig); ok {
		r0 = rf(ctx)
	} else {
		r0 = ret.Get(0).(pubsub.TopicConfig)
	}

	if rf, ok := ret.Get(1).(func(context.Context) error); ok {
		r1 = rf(ctx)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// Delete provides a mock function with given fields: ctx
func (_m *Topic) Delete(ctx context.Context) error {
	ret := _m.Called(ctx)

	if len(ret) == 0 {
		panic("no return value specified for Delete")
	}

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context) error); ok {
		r0 = rf(ctx)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// Exists provides a mock function with given fields: ctx
func (_m *Topic) Exists(ctx context.Context) (bool, error) {
	ret := _m.Called(ctx)

	if len(ret) == 0 {
		panic("no return value specified for Exists")
	}

	var r0 bool
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context) (bool, error)); ok {
		return rf(ctx)
	}
	if rf, ok := ret.Get(0).(func(context.Context) bool); ok {
		r0 = rf(ctx)
	} else {
		r0 = ret.Get(0).(bool)
	}

	if rf, ok := ret.Get(1).(func(context.Context) error); ok {
		r1 = rf(ctx)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// Flush provides a mock function with no fields
func (_m *Topic) Flush() {
	_m.Called()
}

// IAM provides a mock function with no fields
func (_m *Topic) IAM() *iam.Handle {
	ret := _m.Called()

	if len(ret) == 0 {
		panic("no return value specified for IAM")
	}

	var r0 *iam.Handle
	if rf, ok := ret.Get(0).(func() *iam.Handle); ok {
		r0 = rf()
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*iam.Handle)
		}
	}

	return r0
}

// ID provides a mock function with no fields
func (_m *Topic) ID() string {
	ret := _m.Called()

	if len(ret) == 0 {
		panic("no return value specified for ID")
	}

	var r0 string
	if rf, ok := ret.Get(0).(func() string); ok {
		r0 = rf()
	} else {
		r0 = ret.Get(0).(string)
	}

	return r0
}

// Publish provides a mock function with given fields: ctx, msg
func (_m *Topic) Publish(ctx context.Context, msg *pubsub.Message) gopubsub.PublishResult {
	ret := _m.Called(ctx, msg)

	if len(ret) == 0 {
		panic("no return value specified for Publish")
	}

	var r0 gopubsub.PublishResult
	if rf, ok := ret.Get(0).(func(context.Context, *pubsub.Message) gopubsub.PublishResult); ok {
		r0 = rf(ctx, msg)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(gopubsub.PublishResult)
		}
	}

	return r0
}

// ResumePublish provides a mock function with given fields: orderingKey
func (_m *Topic) ResumePublish(orderingKey string) {
	_m.Called(orderingKey)
}

// Stop provides a mock function with no fields
func (_m *Topic) Stop() {
	_m.Called()
}

// String provides a mock function with no fields
func (_m *Topic) String() string {
	ret := _m.Called()

	if len(ret) == 0 {
		panic("no return value specified for String")
	}

	var r0 string
	if rf, ok := ret.Get(0).(func() string); ok {
		r0 = rf()
	} else {
		r0 = ret.Get(0).(string)
	}

	return r0
}

// Subscriptions provides a mock function with given fields: ctx
func (_m *Topic) Subscriptions(ctx context.Context) *pubsub.SubscriptionIterator {
	ret := _m.Called(ctx)

	if len(ret) == 0 {
		panic("no return value specified for Subscriptions")
	}

	var r0 *pubsub.SubscriptionIterator
	if rf, ok := ret.Get(0).(func(context.Context) *pubsub.SubscriptionIterator); ok {
		r0 = rf(ctx)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*pubsub.SubscriptionIterator)
		}
	}

	return r0
}

// Update provides a mock function with given fields: ctx, cfg
func (_m *Topic) Update(ctx context.Context, cfg pubsub.TopicConfigToUpdate) (pubsub.TopicConfig, error) {
	ret := _m.Called(ctx, cfg)

	if len(ret) == 0 {
		panic("no return value specified for Update")
	}

	var r0 pubsub.TopicConfig
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, pubsub.TopicConfigToUpdate) (pubsub.TopicConfig, error)); ok {
		return rf(ctx, cfg)
	}
	if rf, ok := ret.Get(0).(func(context.Context, pubsub.TopicConfigToUpdate) pubsub.TopicConfig); ok {
		r0 = rf(ctx, cfg)
	} else {
		r0 = ret.Get(0).(pubsub.TopicConfig)
	}

	if rf, ok := ret.Get(1).(func(context.Context, pubsub.TopicConfigToUpdate) error); ok {
		r1 = rf(ctx, cfg)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// NewTopic creates a new instance of Topic. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewTopic(t interface {
	mock.TestingT
	Cleanup(func())
}) *Topic {
	mock := &Topic{}
	mock.Mock.Test(t)

	t.Cleanup(func() { mock.AssertExpectations(t) })

	return mock
}
