// Package mock provides mock implementations for testing
package mock

import (
	"context"

	"github.com/pfeifferj/container-mom-go/pkg/operator/mongodb/api"
	"github.com/stretchr/testify/mock"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

// MockMongoDB is a mock implementation of the MongoDB interface
type MockMongoDB struct {
	mock.Mock
}

// NewMockMongoDB creates a new mock MongoDB client
func NewMockMongoDB() *MockMongoDB {
	return &MockMongoDB{}
}

// GetDeployment implements the MongoDB interface
func (m *MockMongoDB) GetDeployment(ctx context.Context, id string) (*api.MongoDeployment, error) {
	args := m.Mock.Called(ctx, id)
	if args.Get(0) == nil {
		return nil, args.Error(1)
	}
	return args.Get(0).(*api.MongoDeployment), args.Error(1)
}

// ListDeployments implements the MongoDB interface
func (m *MockMongoDB) ListDeployments(ctx context.Context) ([]api.MongoDeployment, error) {
	args := m.Mock.Called(ctx)
	return args.Get(0).([]api.MongoDeployment), args.Error(1)
}

// CreateDeployment implements the MongoDB interface
func (m *MockMongoDB) CreateDeployment(ctx context.Context, deployment *api.MongoDeployment) error {
	args := m.Mock.Called(ctx, deployment)
	return args.Error(0)
}

// UpdateDeployment implements the MongoDB interface
func (m *MockMongoDB) UpdateDeployment(ctx context.Context, deployment *api.MongoDeployment) error {
	args := m.Mock.Called(ctx, deployment)
	return args.Error(0)
}

// DeleteDeployment implements the MongoDB interface
func (m *MockMongoDB) DeleteDeployment(ctx context.Context, id string) error {
	args := m.Mock.Called(ctx, id)
	return args.Error(0)
}

// Ping implements a mock ping
func (m *MockMongoDB) Ping(ctx context.Context, opts interface{}) error {
	args := m.Mock.Called(ctx, opts)
	return args.Error(0)
}

// GetClient returns a mock mongo client
func (m *MockMongoDB) GetClient() *mongo.Client {
	args := m.Mock.Called()
	if args.Get(0) == nil {
		client, _ := mongo.Connect(context.Background(), options.Client())
		return client
	}
	return args.Get(0).(*mongo.Client)
}

// Disconnect implements mock disconnect
func (m *MockMongoDB) Disconnect(ctx context.Context) error {
	args := m.Mock.Called(ctx)
	return args.Error(0)
}

// Database returns a mock database
func (m *MockMongoDB) Database(name string) *mongo.Database {
	args := m.Mock.Called(name)
	if args.Get(0) == nil {
		client := m.GetClient()
		return client.Database(name)
	}
	return args.Get(0).(*mongo.Database)
}

// DeleteAllDeployments implements mock delete all
func (m *MockMongoDB) DeleteAllDeployments(ctx context.Context) error {
	args := m.Mock.Called(ctx)
	return args.Error(0)
}
