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

package mocks

import (
	context "context"

	mock "github.com/stretchr/testify/mock"
	v1 "go.skia.org/infra/perf/go/anomalygroup/proto/v1"
)

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

// AddAnomalyID provides a mock function with given fields: ctx, group_id, anomaly_id
func (_m *Store) AddAnomalyID(ctx context.Context, group_id string, anomaly_id string) error {
	ret := _m.Called(ctx, group_id, anomaly_id)

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

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

	return r0
}

// AddCulpritIDs provides a mock function with given fields: ctx, group_id, culprit_ids
func (_m *Store) AddCulpritIDs(ctx context.Context, group_id string, culprit_ids []string) error {
	ret := _m.Called(ctx, group_id, culprit_ids)

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

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

	return r0
}

// Create provides a mock function with given fields: ctx, subscription_name, subscription_revision, domain_name, benchmark_name, start_commit, end_commit, action
func (_m *Store) Create(ctx context.Context, subscription_name string, subscription_revision string, domain_name string, benchmark_name string, start_commit int64, end_commit int64, action string) (string, error) {
	ret := _m.Called(ctx, subscription_name, subscription_revision, domain_name, benchmark_name, start_commit, end_commit, action)

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

	var r0 string
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string, int64, int64, string) (string, error)); ok {
		return rf(ctx, subscription_name, subscription_revision, domain_name, benchmark_name, start_commit, end_commit, action)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string, int64, int64, string) string); ok {
		r0 = rf(ctx, subscription_name, subscription_revision, domain_name, benchmark_name, start_commit, end_commit, action)
	} else {
		r0 = ret.Get(0).(string)
	}

	if rf, ok := ret.Get(1).(func(context.Context, string, string, string, string, int64, int64, string) error); ok {
		r1 = rf(ctx, subscription_name, subscription_revision, domain_name, benchmark_name, start_commit, end_commit, action)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// FindExistingGroup provides a mock function with given fields: ctx, subscription_name, subscription_revision, domain_name, benchmark_name, start_commit, end_commit, action
func (_m *Store) FindExistingGroup(ctx context.Context, subscription_name string, subscription_revision string, domain_name string, benchmark_name string, start_commit int64, end_commit int64, action string) ([]*v1.AnomalyGroup, error) {
	ret := _m.Called(ctx, subscription_name, subscription_revision, domain_name, benchmark_name, start_commit, end_commit, action)

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

	var r0 []*v1.AnomalyGroup
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string, int64, int64, string) ([]*v1.AnomalyGroup, error)); ok {
		return rf(ctx, subscription_name, subscription_revision, domain_name, benchmark_name, start_commit, end_commit, action)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string, int64, int64, string) []*v1.AnomalyGroup); ok {
		r0 = rf(ctx, subscription_name, subscription_revision, domain_name, benchmark_name, start_commit, end_commit, action)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]*v1.AnomalyGroup)
		}
	}

	if rf, ok := ret.Get(1).(func(context.Context, string, string, string, string, int64, int64, string) error); ok {
		r1 = rf(ctx, subscription_name, subscription_revision, domain_name, benchmark_name, start_commit, end_commit, action)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// LoadById provides a mock function with given fields: ctx, group_id
func (_m *Store) LoadById(ctx context.Context, group_id string) (*v1.AnomalyGroup, error) {
	ret := _m.Called(ctx, group_id)

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

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

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

	return r0, r1
}

// UpdateBisectID provides a mock function with given fields: ctx, group_id, bisection_id
func (_m *Store) UpdateBisectID(ctx context.Context, group_id string, bisection_id string) error {
	ret := _m.Called(ctx, group_id, bisection_id)

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

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

	return r0
}

// UpdateReportedIssueID provides a mock function with given fields: ctx, group_id, reported_issue_id
func (_m *Store) UpdateReportedIssueID(ctx context.Context, group_id string, reported_issue_id string) error {
	ret := _m.Called(ctx, group_id, reported_issue_id)

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

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

	return r0
}

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

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

	return mock
}
