// Code generated by http://github.com/gojuno/minimock (v3.3.14). DO NOT EDIT.

package mocks

//go:generate minimock -i git.dmitriygnatenko.ru/dima/homethings/internal/api/v1/tag.ThingRepository -o thing_repository_minimock.go -n ThingRepositoryMock -p mocks

import (
	"context"
	"sync"
	mm_atomic "sync/atomic"
	mm_time "time"

	"git.dmitriygnatenko.ru/dima/homethings/internal/models"
	"github.com/gojuno/minimock/v3"
)

// ThingRepositoryMock implements tag.ThingRepository
type ThingRepositoryMock struct {
	t          minimock.Tester
	finishOnce sync.Once

	funcGet          func(ctx context.Context, id uint64) (tp1 *models.Thing, err error)
	inspectFuncGet   func(ctx context.Context, id uint64)
	afterGetCounter  uint64
	beforeGetCounter uint64
	GetMock          mThingRepositoryMockGet
}

// NewThingRepositoryMock returns a mock for tag.ThingRepository
func NewThingRepositoryMock(t minimock.Tester) *ThingRepositoryMock {
	m := &ThingRepositoryMock{t: t}

	if controller, ok := t.(minimock.MockController); ok {
		controller.RegisterMocker(m)
	}

	m.GetMock = mThingRepositoryMockGet{mock: m}
	m.GetMock.callArgs = []*ThingRepositoryMockGetParams{}

	t.Cleanup(m.MinimockFinish)

	return m
}

type mThingRepositoryMockGet struct {
	optional           bool
	mock               *ThingRepositoryMock
	defaultExpectation *ThingRepositoryMockGetExpectation
	expectations       []*ThingRepositoryMockGetExpectation

	callArgs []*ThingRepositoryMockGetParams
	mutex    sync.RWMutex

	expectedInvocations uint64
}

// ThingRepositoryMockGetExpectation specifies expectation struct of the ThingRepository.Get
type ThingRepositoryMockGetExpectation struct {
	mock      *ThingRepositoryMock
	params    *ThingRepositoryMockGetParams
	paramPtrs *ThingRepositoryMockGetParamPtrs
	results   *ThingRepositoryMockGetResults
	Counter   uint64
}

// ThingRepositoryMockGetParams contains parameters of the ThingRepository.Get
type ThingRepositoryMockGetParams struct {
	ctx context.Context
	id  uint64
}

// ThingRepositoryMockGetParamPtrs contains pointers to parameters of the ThingRepository.Get
type ThingRepositoryMockGetParamPtrs struct {
	ctx *context.Context
	id  *uint64
}

// ThingRepositoryMockGetResults contains results of the ThingRepository.Get
type ThingRepositoryMockGetResults struct {
	tp1 *models.Thing
	err error
}

// Marks this method to be optional. The default behavior of any method with Return() is '1 or more', meaning
// the test will fail minimock's automatic final call check if the mocked method was not called at least once.
// Optional() makes method check to work in '0 or more' mode.
// It is NOT RECOMMENDED to use this option unless you really need it, as default behaviour helps to
// catch the problems when the expected method call is totally skipped during test run.
func (mmGet *mThingRepositoryMockGet) Optional() *mThingRepositoryMockGet {
	mmGet.optional = true
	return mmGet
}

// Expect sets up expected params for ThingRepository.Get
func (mmGet *mThingRepositoryMockGet) Expect(ctx context.Context, id uint64) *mThingRepositoryMockGet {
	if mmGet.mock.funcGet != nil {
		mmGet.mock.t.Fatalf("ThingRepositoryMock.Get mock is already set by Set")
	}

	if mmGet.defaultExpectation == nil {
		mmGet.defaultExpectation = &ThingRepositoryMockGetExpectation{}
	}

	if mmGet.defaultExpectation.paramPtrs != nil {
		mmGet.mock.t.Fatalf("ThingRepositoryMock.Get mock is already set by ExpectParams functions")
	}

	mmGet.defaultExpectation.params = &ThingRepositoryMockGetParams{ctx, id}
	for _, e := range mmGet.expectations {
		if minimock.Equal(e.params, mmGet.defaultExpectation.params) {
			mmGet.mock.t.Fatalf("Expectation set by When has same params: %#v", *mmGet.defaultExpectation.params)
		}
	}

	return mmGet
}

// ExpectCtxParam1 sets up expected param ctx for ThingRepository.Get
func (mmGet *mThingRepositoryMockGet) ExpectCtxParam1(ctx context.Context) *mThingRepositoryMockGet {
	if mmGet.mock.funcGet != nil {
		mmGet.mock.t.Fatalf("ThingRepositoryMock.Get mock is already set by Set")
	}

	if mmGet.defaultExpectation == nil {
		mmGet.defaultExpectation = &ThingRepositoryMockGetExpectation{}
	}

	if mmGet.defaultExpectation.params != nil {
		mmGet.mock.t.Fatalf("ThingRepositoryMock.Get mock is already set by Expect")
	}

	if mmGet.defaultExpectation.paramPtrs == nil {
		mmGet.defaultExpectation.paramPtrs = &ThingRepositoryMockGetParamPtrs{}
	}
	mmGet.defaultExpectation.paramPtrs.ctx = &ctx

	return mmGet
}

// ExpectIdParam2 sets up expected param id for ThingRepository.Get
func (mmGet *mThingRepositoryMockGet) ExpectIdParam2(id uint64) *mThingRepositoryMockGet {
	if mmGet.mock.funcGet != nil {
		mmGet.mock.t.Fatalf("ThingRepositoryMock.Get mock is already set by Set")
	}

	if mmGet.defaultExpectation == nil {
		mmGet.defaultExpectation = &ThingRepositoryMockGetExpectation{}
	}

	if mmGet.defaultExpectation.params != nil {
		mmGet.mock.t.Fatalf("ThingRepositoryMock.Get mock is already set by Expect")
	}

	if mmGet.defaultExpectation.paramPtrs == nil {
		mmGet.defaultExpectation.paramPtrs = &ThingRepositoryMockGetParamPtrs{}
	}
	mmGet.defaultExpectation.paramPtrs.id = &id

	return mmGet
}

// Inspect accepts an inspector function that has same arguments as the ThingRepository.Get
func (mmGet *mThingRepositoryMockGet) Inspect(f func(ctx context.Context, id uint64)) *mThingRepositoryMockGet {
	if mmGet.mock.inspectFuncGet != nil {
		mmGet.mock.t.Fatalf("Inspect function is already set for ThingRepositoryMock.Get")
	}

	mmGet.mock.inspectFuncGet = f

	return mmGet
}

// Return sets up results that will be returned by ThingRepository.Get
func (mmGet *mThingRepositoryMockGet) Return(tp1 *models.Thing, err error) *ThingRepositoryMock {
	if mmGet.mock.funcGet != nil {
		mmGet.mock.t.Fatalf("ThingRepositoryMock.Get mock is already set by Set")
	}

	if mmGet.defaultExpectation == nil {
		mmGet.defaultExpectation = &ThingRepositoryMockGetExpectation{mock: mmGet.mock}
	}
	mmGet.defaultExpectation.results = &ThingRepositoryMockGetResults{tp1, err}
	return mmGet.mock
}

// Set uses given function f to mock the ThingRepository.Get method
func (mmGet *mThingRepositoryMockGet) Set(f func(ctx context.Context, id uint64) (tp1 *models.Thing, err error)) *ThingRepositoryMock {
	if mmGet.defaultExpectation != nil {
		mmGet.mock.t.Fatalf("Default expectation is already set for the ThingRepository.Get method")
	}

	if len(mmGet.expectations) > 0 {
		mmGet.mock.t.Fatalf("Some expectations are already set for the ThingRepository.Get method")
	}

	mmGet.mock.funcGet = f
	return mmGet.mock
}

// When sets expectation for the ThingRepository.Get which will trigger the result defined by the following
// Then helper
func (mmGet *mThingRepositoryMockGet) When(ctx context.Context, id uint64) *ThingRepositoryMockGetExpectation {
	if mmGet.mock.funcGet != nil {
		mmGet.mock.t.Fatalf("ThingRepositoryMock.Get mock is already set by Set")
	}

	expectation := &ThingRepositoryMockGetExpectation{
		mock:   mmGet.mock,
		params: &ThingRepositoryMockGetParams{ctx, id},
	}
	mmGet.expectations = append(mmGet.expectations, expectation)
	return expectation
}

// Then sets up ThingRepository.Get return parameters for the expectation previously defined by the When method
func (e *ThingRepositoryMockGetExpectation) Then(tp1 *models.Thing, err error) *ThingRepositoryMock {
	e.results = &ThingRepositoryMockGetResults{tp1, err}
	return e.mock
}

// Times sets number of times ThingRepository.Get should be invoked
func (mmGet *mThingRepositoryMockGet) Times(n uint64) *mThingRepositoryMockGet {
	if n == 0 {
		mmGet.mock.t.Fatalf("Times of ThingRepositoryMock.Get mock can not be zero")
	}
	mm_atomic.StoreUint64(&mmGet.expectedInvocations, n)
	return mmGet
}

func (mmGet *mThingRepositoryMockGet) invocationsDone() bool {
	if len(mmGet.expectations) == 0 && mmGet.defaultExpectation == nil && mmGet.mock.funcGet == nil {
		return true
	}

	totalInvocations := mm_atomic.LoadUint64(&mmGet.mock.afterGetCounter)
	expectedInvocations := mm_atomic.LoadUint64(&mmGet.expectedInvocations)

	return totalInvocations > 0 && (expectedInvocations == 0 || expectedInvocations == totalInvocations)
}

// Get implements tag.ThingRepository
func (mmGet *ThingRepositoryMock) Get(ctx context.Context, id uint64) (tp1 *models.Thing, err error) {
	mm_atomic.AddUint64(&mmGet.beforeGetCounter, 1)
	defer mm_atomic.AddUint64(&mmGet.afterGetCounter, 1)

	if mmGet.inspectFuncGet != nil {
		mmGet.inspectFuncGet(ctx, id)
	}

	mm_params := ThingRepositoryMockGetParams{ctx, id}

	// Record call args
	mmGet.GetMock.mutex.Lock()
	mmGet.GetMock.callArgs = append(mmGet.GetMock.callArgs, &mm_params)
	mmGet.GetMock.mutex.Unlock()

	for _, e := range mmGet.GetMock.expectations {
		if minimock.Equal(*e.params, mm_params) {
			mm_atomic.AddUint64(&e.Counter, 1)
			return e.results.tp1, e.results.err
		}
	}

	if mmGet.GetMock.defaultExpectation != nil {
		mm_atomic.AddUint64(&mmGet.GetMock.defaultExpectation.Counter, 1)
		mm_want := mmGet.GetMock.defaultExpectation.params
		mm_want_ptrs := mmGet.GetMock.defaultExpectation.paramPtrs

		mm_got := ThingRepositoryMockGetParams{ctx, id}

		if mm_want_ptrs != nil {

			if mm_want_ptrs.ctx != nil && !minimock.Equal(*mm_want_ptrs.ctx, mm_got.ctx) {
				mmGet.t.Errorf("ThingRepositoryMock.Get got unexpected parameter ctx, want: %#v, got: %#v%s\n", *mm_want_ptrs.ctx, mm_got.ctx, minimock.Diff(*mm_want_ptrs.ctx, mm_got.ctx))
			}

			if mm_want_ptrs.id != nil && !minimock.Equal(*mm_want_ptrs.id, mm_got.id) {
				mmGet.t.Errorf("ThingRepositoryMock.Get got unexpected parameter id, want: %#v, got: %#v%s\n", *mm_want_ptrs.id, mm_got.id, minimock.Diff(*mm_want_ptrs.id, mm_got.id))
			}

		} else if mm_want != nil && !minimock.Equal(*mm_want, mm_got) {
			mmGet.t.Errorf("ThingRepositoryMock.Get got unexpected parameters, want: %#v, got: %#v%s\n", *mm_want, mm_got, minimock.Diff(*mm_want, mm_got))
		}

		mm_results := mmGet.GetMock.defaultExpectation.results
		if mm_results == nil {
			mmGet.t.Fatal("No results are set for the ThingRepositoryMock.Get")
		}
		return (*mm_results).tp1, (*mm_results).err
	}
	if mmGet.funcGet != nil {
		return mmGet.funcGet(ctx, id)
	}
	mmGet.t.Fatalf("Unexpected call to ThingRepositoryMock.Get. %v %v", ctx, id)
	return
}

// GetAfterCounter returns a count of finished ThingRepositoryMock.Get invocations
func (mmGet *ThingRepositoryMock) GetAfterCounter() uint64 {
	return mm_atomic.LoadUint64(&mmGet.afterGetCounter)
}

// GetBeforeCounter returns a count of ThingRepositoryMock.Get invocations
func (mmGet *ThingRepositoryMock) GetBeforeCounter() uint64 {
	return mm_atomic.LoadUint64(&mmGet.beforeGetCounter)
}

// Calls returns a list of arguments used in each call to ThingRepositoryMock.Get.
// The list is in the same order as the calls were made (i.e. recent calls have a higher index)
func (mmGet *mThingRepositoryMockGet) Calls() []*ThingRepositoryMockGetParams {
	mmGet.mutex.RLock()

	argCopy := make([]*ThingRepositoryMockGetParams, len(mmGet.callArgs))
	copy(argCopy, mmGet.callArgs)

	mmGet.mutex.RUnlock()

	return argCopy
}

// MinimockGetDone returns true if the count of the Get invocations corresponds
// the number of defined expectations
func (m *ThingRepositoryMock) MinimockGetDone() bool {
	if m.GetMock.optional {
		// Optional methods provide '0 or more' call count restriction.
		return true
	}

	for _, e := range m.GetMock.expectations {
		if mm_atomic.LoadUint64(&e.Counter) < 1 {
			return false
		}
	}

	return m.GetMock.invocationsDone()
}

// MinimockGetInspect logs each unmet expectation
func (m *ThingRepositoryMock) MinimockGetInspect() {
	for _, e := range m.GetMock.expectations {
		if mm_atomic.LoadUint64(&e.Counter) < 1 {
			m.t.Errorf("Expected call to ThingRepositoryMock.Get with params: %#v", *e.params)
		}
	}

	afterGetCounter := mm_atomic.LoadUint64(&m.afterGetCounter)
	// if default expectation was set then invocations count should be greater than zero
	if m.GetMock.defaultExpectation != nil && afterGetCounter < 1 {
		if m.GetMock.defaultExpectation.params == nil {
			m.t.Error("Expected call to ThingRepositoryMock.Get")
		} else {
			m.t.Errorf("Expected call to ThingRepositoryMock.Get with params: %#v", *m.GetMock.defaultExpectation.params)
		}
	}
	// if func was set then invocations count should be greater than zero
	if m.funcGet != nil && afterGetCounter < 1 {
		m.t.Error("Expected call to ThingRepositoryMock.Get")
	}

	if !m.GetMock.invocationsDone() && afterGetCounter > 0 {
		m.t.Errorf("Expected %d calls to ThingRepositoryMock.Get but found %d calls",
			mm_atomic.LoadUint64(&m.GetMock.expectedInvocations), afterGetCounter)
	}
}

// MinimockFinish checks that all mocked methods have been called the expected number of times
func (m *ThingRepositoryMock) MinimockFinish() {
	m.finishOnce.Do(func() {
		if !m.minimockDone() {
			m.MinimockGetInspect()
		}
	})
}

// MinimockWait waits for all mocked methods to be called the expected number of times
func (m *ThingRepositoryMock) MinimockWait(timeout mm_time.Duration) {
	timeoutCh := mm_time.After(timeout)
	for {
		if m.minimockDone() {
			return
		}
		select {
		case <-timeoutCh:
			m.MinimockFinish()
			return
		case <-mm_time.After(10 * mm_time.Millisecond):
		}
	}
}

func (m *ThingRepositoryMock) minimockDone() bool {
	done := true
	return done &&
		m.MinimockGetDone()
}
