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

package mocks

import (
	context "context"

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

	time "time"

	v1 "go.chromium.org/luci/common/api/swarming/swarming/v1"
)

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

// CancelTask provides a mock function with given fields: ctx, id, killRunning
func (_m *ApiClient) CancelTask(ctx context.Context, id string, killRunning bool) error {
	ret := _m.Called(ctx, id, killRunning)

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

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

	return r0
}

// DeleteBots provides a mock function with given fields: ctx, bots
func (_m *ApiClient) DeleteBots(ctx context.Context, bots []string) error {
	ret := _m.Called(ctx, bots)

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

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

	return r0
}

// GetStates provides a mock function with given fields: ctx, ids
func (_m *ApiClient) GetStates(ctx context.Context, ids []string) ([]string, error) {
	ret := _m.Called(ctx, ids)

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

	var r0 []string
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, []string) ([]string, error)); ok {
		return rf(ctx, ids)
	}
	if rf, ok := ret.Get(0).(func(context.Context, []string) []string); ok {
		r0 = rf(ctx, ids)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]string)
		}
	}

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

	return r0, r1
}

// GetStdoutOfTask provides a mock function with given fields: ctx, id
func (_m *ApiClient) GetStdoutOfTask(ctx context.Context, id string) (*v1.SwarmingRpcsTaskOutput, error) {
	ret := _m.Called(ctx, id)

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

	var r0 *v1.SwarmingRpcsTaskOutput
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string) (*v1.SwarmingRpcsTaskOutput, error)); ok {
		return rf(ctx, id)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string) *v1.SwarmingRpcsTaskOutput); ok {
		r0 = rf(ctx, id)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*v1.SwarmingRpcsTaskOutput)
		}
	}

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

	return r0, r1
}

// GetTask provides a mock function with given fields: ctx, id, includePerformanceStats
func (_m *ApiClient) GetTask(ctx context.Context, id string, includePerformanceStats bool) (*v1.SwarmingRpcsTaskResult, error) {
	ret := _m.Called(ctx, id, includePerformanceStats)

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

	var r0 *v1.SwarmingRpcsTaskResult
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string, bool) (*v1.SwarmingRpcsTaskResult, error)); ok {
		return rf(ctx, id, includePerformanceStats)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string, bool) *v1.SwarmingRpcsTaskResult); ok {
		r0 = rf(ctx, id, includePerformanceStats)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*v1.SwarmingRpcsTaskResult)
		}
	}

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

	return r0, r1
}

// GetTaskMetadata provides a mock function with given fields: ctx, id
func (_m *ApiClient) GetTaskMetadata(ctx context.Context, id string) (*v1.SwarmingRpcsTaskRequestMetadata, error) {
	ret := _m.Called(ctx, id)

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

	var r0 *v1.SwarmingRpcsTaskRequestMetadata
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string) (*v1.SwarmingRpcsTaskRequestMetadata, error)); ok {
		return rf(ctx, id)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string) *v1.SwarmingRpcsTaskRequestMetadata); ok {
		r0 = rf(ctx, id)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*v1.SwarmingRpcsTaskRequestMetadata)
		}
	}

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

	return r0, r1
}

// GracefullyShutdownBot provides a mock function with given fields: ctx, id
func (_m *ApiClient) GracefullyShutdownBot(ctx context.Context, id string) (*v1.SwarmingRpcsTerminateResponse, error) {
	ret := _m.Called(ctx, id)

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

	var r0 *v1.SwarmingRpcsTerminateResponse
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string) (*v1.SwarmingRpcsTerminateResponse, error)); ok {
		return rf(ctx, id)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string) *v1.SwarmingRpcsTerminateResponse); ok {
		r0 = rf(ctx, id)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*v1.SwarmingRpcsTerminateResponse)
		}
	}

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

	return r0, r1
}

// ListBotTasks provides a mock function with given fields: ctx, botID, limit
func (_m *ApiClient) ListBotTasks(ctx context.Context, botID string, limit int) ([]*v1.SwarmingRpcsTaskResult, error) {
	ret := _m.Called(ctx, botID, limit)

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

	var r0 []*v1.SwarmingRpcsTaskResult
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string, int) ([]*v1.SwarmingRpcsTaskResult, error)); ok {
		return rf(ctx, botID, limit)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string, int) []*v1.SwarmingRpcsTaskResult); ok {
		r0 = rf(ctx, botID, limit)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]*v1.SwarmingRpcsTaskResult)
		}
	}

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

	return r0, r1
}

// ListBots provides a mock function with given fields: ctx, dimensions
func (_m *ApiClient) ListBots(ctx context.Context, dimensions map[string]string) ([]*v1.SwarmingRpcsBotInfo, error) {
	ret := _m.Called(ctx, dimensions)

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

	var r0 []*v1.SwarmingRpcsBotInfo
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, map[string]string) ([]*v1.SwarmingRpcsBotInfo, error)); ok {
		return rf(ctx, dimensions)
	}
	if rf, ok := ret.Get(0).(func(context.Context, map[string]string) []*v1.SwarmingRpcsBotInfo); ok {
		r0 = rf(ctx, dimensions)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]*v1.SwarmingRpcsBotInfo)
		}
	}

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

	return r0, r1
}

// ListBotsForPool provides a mock function with given fields: ctx, pool
func (_m *ApiClient) ListBotsForPool(ctx context.Context, pool string) ([]*v1.SwarmingRpcsBotInfo, error) {
	ret := _m.Called(ctx, pool)

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

	var r0 []*v1.SwarmingRpcsBotInfo
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string) ([]*v1.SwarmingRpcsBotInfo, error)); ok {
		return rf(ctx, pool)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string) []*v1.SwarmingRpcsBotInfo); ok {
		r0 = rf(ctx, pool)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]*v1.SwarmingRpcsBotInfo)
		}
	}

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

	return r0, r1
}

// ListDownBots provides a mock function with given fields: ctx, pool
func (_m *ApiClient) ListDownBots(ctx context.Context, pool string) ([]*v1.SwarmingRpcsBotInfo, error) {
	ret := _m.Called(ctx, pool)

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

	var r0 []*v1.SwarmingRpcsBotInfo
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string) ([]*v1.SwarmingRpcsBotInfo, error)); ok {
		return rf(ctx, pool)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string) []*v1.SwarmingRpcsBotInfo); ok {
		r0 = rf(ctx, pool)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]*v1.SwarmingRpcsBotInfo)
		}
	}

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

	return r0, r1
}

// ListFreeBots provides a mock function with given fields: ctx, pool
func (_m *ApiClient) ListFreeBots(ctx context.Context, pool string) ([]*v1.SwarmingRpcsBotInfo, error) {
	ret := _m.Called(ctx, pool)

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

	var r0 []*v1.SwarmingRpcsBotInfo
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string) ([]*v1.SwarmingRpcsBotInfo, error)); ok {
		return rf(ctx, pool)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string) []*v1.SwarmingRpcsBotInfo); ok {
		r0 = rf(ctx, pool)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]*v1.SwarmingRpcsBotInfo)
		}
	}

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

	return r0, r1
}

// ListSkiaTasks provides a mock function with given fields: ctx, start, end
func (_m *ApiClient) ListSkiaTasks(ctx context.Context, start time.Time, end time.Time) ([]*v1.SwarmingRpcsTaskRequestMetadata, error) {
	ret := _m.Called(ctx, start, end)

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

	var r0 []*v1.SwarmingRpcsTaskRequestMetadata
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, time.Time, time.Time) ([]*v1.SwarmingRpcsTaskRequestMetadata, error)); ok {
		return rf(ctx, start, end)
	}
	if rf, ok := ret.Get(0).(func(context.Context, time.Time, time.Time) []*v1.SwarmingRpcsTaskRequestMetadata); ok {
		r0 = rf(ctx, start, end)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]*v1.SwarmingRpcsTaskRequestMetadata)
		}
	}

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

	return r0, r1
}

// ListTaskResults provides a mock function with given fields: ctx, start, end, tags, state, includePerformanceStats
func (_m *ApiClient) ListTaskResults(ctx context.Context, start time.Time, end time.Time, tags []string, state string, includePerformanceStats bool) ([]*v1.SwarmingRpcsTaskResult, error) {
	ret := _m.Called(ctx, start, end, tags, state, includePerformanceStats)

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

	var r0 []*v1.SwarmingRpcsTaskResult
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, time.Time, time.Time, []string, string, bool) ([]*v1.SwarmingRpcsTaskResult, error)); ok {
		return rf(ctx, start, end, tags, state, includePerformanceStats)
	}
	if rf, ok := ret.Get(0).(func(context.Context, time.Time, time.Time, []string, string, bool) []*v1.SwarmingRpcsTaskResult); ok {
		r0 = rf(ctx, start, end, tags, state, includePerformanceStats)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]*v1.SwarmingRpcsTaskResult)
		}
	}

	if rf, ok := ret.Get(1).(func(context.Context, time.Time, time.Time, []string, string, bool) error); ok {
		r1 = rf(ctx, start, end, tags, state, includePerformanceStats)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// ListTasks provides a mock function with given fields: ctx, start, end, tags, state
func (_m *ApiClient) ListTasks(ctx context.Context, start time.Time, end time.Time, tags []string, state string) ([]*v1.SwarmingRpcsTaskRequestMetadata, error) {
	ret := _m.Called(ctx, start, end, tags, state)

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

	var r0 []*v1.SwarmingRpcsTaskRequestMetadata
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, time.Time, time.Time, []string, string) ([]*v1.SwarmingRpcsTaskRequestMetadata, error)); ok {
		return rf(ctx, start, end, tags, state)
	}
	if rf, ok := ret.Get(0).(func(context.Context, time.Time, time.Time, []string, string) []*v1.SwarmingRpcsTaskRequestMetadata); ok {
		r0 = rf(ctx, start, end, tags, state)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]*v1.SwarmingRpcsTaskRequestMetadata)
		}
	}

	if rf, ok := ret.Get(1).(func(context.Context, time.Time, time.Time, []string, string) error); ok {
		r1 = rf(ctx, start, end, tags, state)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// RetryTask provides a mock function with given fields: ctx, t
func (_m *ApiClient) RetryTask(ctx context.Context, t *v1.SwarmingRpcsTaskRequestMetadata) (*v1.SwarmingRpcsTaskRequestMetadata, error) {
	ret := _m.Called(ctx, t)

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

	var r0 *v1.SwarmingRpcsTaskRequestMetadata
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, *v1.SwarmingRpcsTaskRequestMetadata) (*v1.SwarmingRpcsTaskRequestMetadata, error)); ok {
		return rf(ctx, t)
	}
	if rf, ok := ret.Get(0).(func(context.Context, *v1.SwarmingRpcsTaskRequestMetadata) *v1.SwarmingRpcsTaskRequestMetadata); ok {
		r0 = rf(ctx, t)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*v1.SwarmingRpcsTaskRequestMetadata)
		}
	}

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

	return r0, r1
}

// SwarmingService provides a mock function with given fields:
func (_m *ApiClient) SwarmingService() *v1.Service {
	ret := _m.Called()

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

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

	return r0
}

// TriggerTask provides a mock function with given fields: ctx, t
func (_m *ApiClient) TriggerTask(ctx context.Context, t *v1.SwarmingRpcsNewTaskRequest) (*v1.SwarmingRpcsTaskRequestMetadata, error) {
	ret := _m.Called(ctx, t)

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

	var r0 *v1.SwarmingRpcsTaskRequestMetadata
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, *v1.SwarmingRpcsNewTaskRequest) (*v1.SwarmingRpcsTaskRequestMetadata, error)); ok {
		return rf(ctx, t)
	}
	if rf, ok := ret.Get(0).(func(context.Context, *v1.SwarmingRpcsNewTaskRequest) *v1.SwarmingRpcsTaskRequestMetadata); ok {
		r0 = rf(ctx, t)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*v1.SwarmingRpcsTaskRequestMetadata)
		}
	}

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

	return r0, r1
}

// NewApiClient creates a new instance of ApiClient. 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 NewApiClient(t interface {
	mock.TestingT
	Cleanup(func())
}) *ApiClient {
	mock := &ApiClient{}
	mock.Mock.Test(t)

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

	return mock
}
