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

package mocks

import (
	context "context"
	time "time"

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

	vcsinfo "go.skia.org/infra/go/vcsinfo"
)

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

// ByIndex provides a mock function with given fields: ctx, N
func (_m *VCS) ByIndex(ctx context.Context, N int) (*vcsinfo.LongCommit, error) {
	ret := _m.Called(ctx, N)

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

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

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

	return r0, r1
}

// Details provides a mock function with given fields: ctx, hash, includeBranchInfo
func (_m *VCS) Details(ctx context.Context, hash string, includeBranchInfo bool) (*vcsinfo.LongCommit, error) {
	ret := _m.Called(ctx, hash, includeBranchInfo)

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

	var r0 *vcsinfo.LongCommit
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string, bool) (*vcsinfo.LongCommit, error)); ok {
		return rf(ctx, hash, includeBranchInfo)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string, bool) *vcsinfo.LongCommit); ok {
		r0 = rf(ctx, hash, includeBranchInfo)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*vcsinfo.LongCommit)
		}
	}

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

	return r0, r1
}

// DetailsMulti provides a mock function with given fields: ctx, hashes, includeBranchInfo
func (_m *VCS) DetailsMulti(ctx context.Context, hashes []string, includeBranchInfo bool) ([]*vcsinfo.LongCommit, error) {
	ret := _m.Called(ctx, hashes, includeBranchInfo)

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

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

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

	return r0, r1
}

// From provides a mock function with given fields: start
func (_m *VCS) From(start time.Time) []string {
	ret := _m.Called(start)

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

	var r0 []string
	if rf, ok := ret.Get(0).(func(time.Time) []string); ok {
		r0 = rf(start)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]string)
		}
	}

	return r0
}

// IndexOf provides a mock function with given fields: ctx, hash
func (_m *VCS) IndexOf(ctx context.Context, hash string) (int, error) {
	ret := _m.Called(ctx, hash)

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

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

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

	return r0, r1
}

// LastNIndex provides a mock function with given fields: N
func (_m *VCS) LastNIndex(N int) []*vcsinfo.IndexCommit {
	ret := _m.Called(N)

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

	var r0 []*vcsinfo.IndexCommit
	if rf, ok := ret.Get(0).(func(int) []*vcsinfo.IndexCommit); ok {
		r0 = rf(N)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]*vcsinfo.IndexCommit)
		}
	}

	return r0
}

// Range provides a mock function with given fields: begin, end
func (_m *VCS) Range(begin time.Time, end time.Time) []*vcsinfo.IndexCommit {
	ret := _m.Called(begin, end)

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

	var r0 []*vcsinfo.IndexCommit
	if rf, ok := ret.Get(0).(func(time.Time, time.Time) []*vcsinfo.IndexCommit); ok {
		r0 = rf(begin, end)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]*vcsinfo.IndexCommit)
		}
	}

	return r0
}

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

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

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

	return r0
}

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

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

	return mock
}
