//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//

// Code generated by MockGen. DO NOT EDIT.
// Source: ./cloudstack/StratosphereSSPService.go

// Package cloudstack is a generated GoMock package.
package cloudstack

import (
	reflect "reflect"

	gomock "github.com/golang/mock/gomock"
)

// MockStratosphereSSPServiceIface is a mock of StratosphereSSPServiceIface interface.
type MockStratosphereSSPServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockStratosphereSSPServiceIfaceMockRecorder
}

// MockStratosphereSSPServiceIfaceMockRecorder is the mock recorder for MockStratosphereSSPServiceIface.
type MockStratosphereSSPServiceIfaceMockRecorder struct {
	mock *MockStratosphereSSPServiceIface
}

// NewMockStratosphereSSPServiceIface creates a new mock instance.
func NewMockStratosphereSSPServiceIface(ctrl *gomock.Controller) *MockStratosphereSSPServiceIface {
	mock := &MockStratosphereSSPServiceIface{ctrl: ctrl}
	mock.recorder = &MockStratosphereSSPServiceIfaceMockRecorder{mock}
	return mock
}

// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockStratosphereSSPServiceIface) EXPECT() *MockStratosphereSSPServiceIfaceMockRecorder {
	return m.recorder
}

// AddStratosphereSsp mocks base method.
func (m *MockStratosphereSSPServiceIface) AddStratosphereSsp(p *AddStratosphereSspParams) (*AddStratosphereSspResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "AddStratosphereSsp", p)
	ret0, _ := ret[0].(*AddStratosphereSspResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// AddStratosphereSsp indicates an expected call of AddStratosphereSsp.
func (mr *MockStratosphereSSPServiceIfaceMockRecorder) AddStratosphereSsp(p interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddStratosphereSsp", reflect.TypeOf((*MockStratosphereSSPServiceIface)(nil).AddStratosphereSsp), p)
}

// DeleteStratosphereSsp mocks base method.
func (m *MockStratosphereSSPServiceIface) DeleteStratosphereSsp(p *DeleteStratosphereSspParams) (*DeleteStratosphereSspResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteStratosphereSsp", p)
	ret0, _ := ret[0].(*DeleteStratosphereSspResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeleteStratosphereSsp indicates an expected call of DeleteStratosphereSsp.
func (mr *MockStratosphereSSPServiceIfaceMockRecorder) DeleteStratosphereSsp(p interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteStratosphereSsp", reflect.TypeOf((*MockStratosphereSSPServiceIface)(nil).DeleteStratosphereSsp), p)
}

// NewAddStratosphereSspParams mocks base method.
func (m *MockStratosphereSSPServiceIface) NewAddStratosphereSspParams(name, url, zoneid string) *AddStratosphereSspParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewAddStratosphereSspParams", name, url, zoneid)
	ret0, _ := ret[0].(*AddStratosphereSspParams)
	return ret0
}

// NewAddStratosphereSspParams indicates an expected call of NewAddStratosphereSspParams.
func (mr *MockStratosphereSSPServiceIfaceMockRecorder) NewAddStratosphereSspParams(name, url, zoneid interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddStratosphereSspParams", reflect.TypeOf((*MockStratosphereSSPServiceIface)(nil).NewAddStratosphereSspParams), name, url, zoneid)
}

// NewDeleteStratosphereSspParams mocks base method.
func (m *MockStratosphereSSPServiceIface) NewDeleteStratosphereSspParams(hostid string) *DeleteStratosphereSspParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDeleteStratosphereSspParams", hostid)
	ret0, _ := ret[0].(*DeleteStratosphereSspParams)
	return ret0
}

// NewDeleteStratosphereSspParams indicates an expected call of NewDeleteStratosphereSspParams.
func (mr *MockStratosphereSSPServiceIfaceMockRecorder) NewDeleteStratosphereSspParams(hostid interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteStratosphereSspParams", reflect.TypeOf((*MockStratosphereSSPServiceIface)(nil).NewDeleteStratosphereSspParams), hostid)
}
