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

package mocks

import (
	context "context"
	fs "io/fs"

	git "go.skia.org/infra/go/git"

	gitiles "go.skia.org/infra/go/gitiles"

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

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

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

// Branches provides a mock function with given fields: ctx
func (_m *GitilesRepo) Branches(ctx context.Context) ([]*git.Branch, error) {
	ret := _m.Called(ctx)

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

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

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

	return r0, r1
}

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

	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) (*vcsinfo.LongCommit, error)); ok {
		return rf(ctx, ref)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string) *vcsinfo.LongCommit); ok {
		r0 = rf(ctx, ref)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*vcsinfo.LongCommit)
		}
	}

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

	return r0, r1
}

// DownloadFile provides a mock function with given fields: ctx, srcPath, dstPath
func (_m *GitilesRepo) DownloadFile(ctx context.Context, srcPath string, dstPath string) error {
	ret := _m.Called(ctx, srcPath, dstPath)

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

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

	return r0
}

// DownloadFileAtRef provides a mock function with given fields: ctx, srcPath, ref, dstPath
func (_m *GitilesRepo) DownloadFileAtRef(ctx context.Context, srcPath string, ref string, dstPath string) error {
	ret := _m.Called(ctx, srcPath, ref, dstPath)

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

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

	return r0
}

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

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

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

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

	return r0, r1
}

// ListDir provides a mock function with given fields: ctx, dir
func (_m *GitilesRepo) ListDir(ctx context.Context, dir string) ([]fs.FileInfo, error) {
	ret := _m.Called(ctx, dir)

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

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

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

	return r0, r1
}

// ListDirAtRef provides a mock function with given fields: ctx, dir, ref
func (_m *GitilesRepo) ListDirAtRef(ctx context.Context, dir string, ref string) ([]fs.FileInfo, error) {
	ret := _m.Called(ctx, dir, ref)

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

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

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

	return r0, r1
}

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

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

	var r0 []string
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string) ([]string, error)); ok {
		return rf(ctx, dir)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string) []string); ok {
		r0 = rf(ctx, dir)
	} 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, dir)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// ListFilesRecursiveAtRef provides a mock function with given fields: ctx, topDir, ref
func (_m *GitilesRepo) ListFilesRecursiveAtRef(ctx context.Context, topDir string, ref string) ([]string, error) {
	ret := _m.Called(ctx, topDir, ref)

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

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

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

	return r0, r1
}

// Log provides a mock function with given fields: ctx, logExpr, opts
func (_m *GitilesRepo) Log(ctx context.Context, logExpr string, opts ...gitiles.LogOption) ([]*vcsinfo.LongCommit, error) {
	_va := make([]interface{}, len(opts))
	for _i := range opts {
		_va[_i] = opts[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, ctx, logExpr)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

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

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

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

	return r0, r1
}

// LogFirstParent provides a mock function with given fields: ctx, from, to, opts
func (_m *GitilesRepo) LogFirstParent(ctx context.Context, from string, to string, opts ...gitiles.LogOption) ([]*vcsinfo.LongCommit, error) {
	_va := make([]interface{}, len(opts))
	for _i := range opts {
		_va[_i] = opts[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, ctx, from, to)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

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

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

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

	return r0, r1
}

// LogFn provides a mock function with given fields: ctx, logExpr, fn, opts
func (_m *GitilesRepo) LogFn(ctx context.Context, logExpr string, fn func(context.Context, *vcsinfo.LongCommit) error, opts ...gitiles.LogOption) error {
	_va := make([]interface{}, len(opts))
	for _i := range opts {
		_va[_i] = opts[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, ctx, logExpr, fn)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

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

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, string, func(context.Context, *vcsinfo.LongCommit) error, ...gitiles.LogOption) error); ok {
		r0 = rf(ctx, logExpr, fn, opts...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// LogFnBatch provides a mock function with given fields: ctx, logExpr, fn, opts
func (_m *GitilesRepo) LogFnBatch(ctx context.Context, logExpr string, fn func(context.Context, []*vcsinfo.LongCommit) error, opts ...gitiles.LogOption) error {
	_va := make([]interface{}, len(opts))
	for _i := range opts {
		_va[_i] = opts[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, ctx, logExpr, fn)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

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

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, string, func(context.Context, []*vcsinfo.LongCommit) error, ...gitiles.LogOption) error); ok {
		r0 = rf(ctx, logExpr, fn, opts...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// LogLinear provides a mock function with given fields: ctx, from, to, opts
func (_m *GitilesRepo) LogLinear(ctx context.Context, from string, to string, opts ...gitiles.LogOption) ([]*vcsinfo.LongCommit, error) {
	_va := make([]interface{}, len(opts))
	for _i := range opts {
		_va[_i] = opts[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, ctx, from, to)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

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

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

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

	return r0, r1
}

// ReadFile provides a mock function with given fields: ctx, srcPath
func (_m *GitilesRepo) ReadFile(ctx context.Context, srcPath string) ([]byte, error) {
	ret := _m.Called(ctx, srcPath)

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

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

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

	return r0, r1
}

// ReadFileAtRef provides a mock function with given fields: ctx, srcPath, ref
func (_m *GitilesRepo) ReadFileAtRef(ctx context.Context, srcPath string, ref string) ([]byte, error) {
	ret := _m.Called(ctx, srcPath, ref)

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

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

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

	return r0, r1
}

// ReadObject provides a mock function with given fields: ctx, path, ref
func (_m *GitilesRepo) ReadObject(ctx context.Context, path string, ref string) (fs.FileInfo, []byte, error) {
	ret := _m.Called(ctx, path, ref)

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

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

	if rf, ok := ret.Get(1).(func(context.Context, string, string) []byte); ok {
		r1 = rf(ctx, path, ref)
	} else {
		if ret.Get(1) != nil {
			r1 = ret.Get(1).([]byte)
		}
	}

	if rf, ok := ret.Get(2).(func(context.Context, string, string) error); ok {
		r2 = rf(ctx, path, ref)
	} else {
		r2 = ret.Error(2)
	}

	return r0, r1, r2
}

// ResolveRef provides a mock function with given fields: ctx, ref
func (_m *GitilesRepo) ResolveRef(ctx context.Context, ref string) (string, error) {
	ret := _m.Called(ctx, ref)

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

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

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

	return r0, r1
}

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

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

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

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

	return r0, r1
}

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

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

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

	return r0
}

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

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

	return mock
}
