// Code generated by mockery v1.0.0. DO NOT EDIT.

package test_gcsclient

import (
	context "context"
	io "io"

	gcs "go.skia.org/infra/go/gcs"

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

	storage "cloud.google.com/go/storage"
)

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

// AllFilesInDirectory provides a mock function with given fields: ctx, prefix, callback
func (_m *GCSClient) AllFilesInDirectory(ctx context.Context, prefix string, callback func(*storage.ObjectAttrs)) error {
	ret := _m.Called(ctx, prefix, callback)

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, string, func(*storage.ObjectAttrs)) error); ok {
		r0 = rf(ctx, prefix, callback)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// Bucket provides a mock function with given fields:
func (_m *GCSClient) Bucket() string {
	ret := _m.Called()

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

	return r0
}

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

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

	return r0
}

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

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

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

	return r0, r1
}

// FileReader provides a mock function with given fields: ctx, path
func (_m *GCSClient) FileReader(ctx context.Context, path string) (io.ReadCloser, error) {
	ret := _m.Called(ctx, path)

	var r0 io.ReadCloser
	if rf, ok := ret.Get(0).(func(context.Context, string) io.ReadCloser); ok {
		r0 = rf(ctx, path)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(io.ReadCloser)
		}
	}

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

	return r0, r1
}

// FileWriter provides a mock function with given fields: ctx, path, opts
func (_m *GCSClient) FileWriter(ctx context.Context, path string, opts gcs.FileWriteOptions) io.WriteCloser {
	ret := _m.Called(ctx, path, opts)

	var r0 io.WriteCloser
	if rf, ok := ret.Get(0).(func(context.Context, string, gcs.FileWriteOptions) io.WriteCloser); ok {
		r0 = rf(ctx, path, opts)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(io.WriteCloser)
		}
	}

	return r0
}

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

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

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

	return r0, r1
}

// GetFileObjectAttrs provides a mock function with given fields: ctx, path
func (_m *GCSClient) GetFileObjectAttrs(ctx context.Context, path string) (*storage.ObjectAttrs, error) {
	ret := _m.Called(ctx, path)

	var r0 *storage.ObjectAttrs
	if rf, ok := ret.Get(0).(func(context.Context, string) *storage.ObjectAttrs); ok {
		r0 = rf(ctx, path)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*storage.ObjectAttrs)
		}
	}

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

	return r0, r1
}

// SetFileContents provides a mock function with given fields: ctx, path, opts, contents
func (_m *GCSClient) SetFileContents(ctx context.Context, path string, opts gcs.FileWriteOptions, contents []byte) error {
	ret := _m.Called(ctx, path, opts, contents)

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, string, gcs.FileWriteOptions, []byte) error); ok {
		r0 = rf(ctx, path, opts, contents)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}
