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

package mocks

import (
	context "context"

	mock "github.com/stretchr/testify/mock"
	specs "go.skia.org/infra/task_scheduler/go/specs"

	task_cfg_cache "go.skia.org/infra/task_scheduler/go/task_cfg_cache"

	time "time"

	types "go.skia.org/infra/task_scheduler/go/types"
)

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

// Cleanup provides a mock function with given fields: ctx, period
func (_m *TaskCfgCache) Cleanup(ctx context.Context, period time.Duration) error {
	ret := _m.Called(ctx, period)

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

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

	return r0
}

// Close provides a mock function with no fields
func (_m *TaskCfgCache) Close() error {
	ret := _m.Called()

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

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

	return r0
}

// Get provides a mock function with given fields: _a0, _a1
func (_m *TaskCfgCache) Get(_a0 context.Context, _a1 types.RepoState) (*specs.TasksCfg, error, error) {
	ret := _m.Called(_a0, _a1)

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

	var r0 *specs.TasksCfg
	var r1 error
	var r2 error
	if rf, ok := ret.Get(0).(func(context.Context, types.RepoState) (*specs.TasksCfg, error, error)); ok {
		return rf(_a0, _a1)
	}
	if rf, ok := ret.Get(0).(func(context.Context, types.RepoState) *specs.TasksCfg); ok {
		r0 = rf(_a0, _a1)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*specs.TasksCfg)
		}
	}

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

	if rf, ok := ret.Get(2).(func(context.Context, types.RepoState) error); ok {
		r2 = rf(_a0, _a1)
	} else {
		r2 = ret.Error(2)
	}

	return r0, r1, r2
}

// Set provides a mock function with given fields: ctx, rs, cfg, storedErr
func (_m *TaskCfgCache) Set(ctx context.Context, rs types.RepoState, cfg *specs.TasksCfg, storedErr error) error {
	ret := _m.Called(ctx, rs, cfg, storedErr)

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

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, types.RepoState, *specs.TasksCfg, error) error); ok {
		r0 = rf(ctx, rs, cfg, storedErr)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// SetIfUnset provides a mock function with given fields: ctx, rs, fn
func (_m *TaskCfgCache) SetIfUnset(ctx context.Context, rs types.RepoState, fn func(context.Context) (*task_cfg_cache.CachedValue, error)) (*task_cfg_cache.CachedValue, error) {
	ret := _m.Called(ctx, rs, fn)

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

	var r0 *task_cfg_cache.CachedValue
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, types.RepoState, func(context.Context) (*task_cfg_cache.CachedValue, error)) (*task_cfg_cache.CachedValue, error)); ok {
		return rf(ctx, rs, fn)
	}
	if rf, ok := ret.Get(0).(func(context.Context, types.RepoState, func(context.Context) (*task_cfg_cache.CachedValue, error)) *task_cfg_cache.CachedValue); ok {
		r0 = rf(ctx, rs, fn)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*task_cfg_cache.CachedValue)
		}
	}

	if rf, ok := ret.Get(1).(func(context.Context, types.RepoState, func(context.Context) (*task_cfg_cache.CachedValue, error)) error); ok {
		r1 = rf(ctx, rs, fn)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

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

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

	return mock
}
