package dht

import (
	"context"
	"github.com/libp2p/go-libp2p/core/peer"
)

// DHT defines the common interface for all DHT implementations
type DHT interface {
	// Core DHT operations
	PutValue(ctx context.Context, key string, value []byte) error
	GetValue(ctx context.Context, key string) ([]byte, error)
	Provide(ctx context.Context, key string) error
	FindProviders(ctx context.Context, key string, limit int) ([]peer.AddrInfo, error)
	
	// Statistics and monitoring
	GetStats() DHTStats
}

// ReplicatedDHT extends DHT with replication capabilities
type ReplicatedDHT interface {
	DHT
	
	// Replication management
	AddContentForReplication(key string, size int64, priority int) error
	RemoveContentFromReplication(key string) error
	GetReplicationStatus(key string) (*ReplicationStatus, error)
	GetReplicationMetrics() *ReplicationMetrics
	
	// Provider management
	FindContentProviders(ctx context.Context, key string, limit int) ([]ProviderInfo, error)
	ProvideContent(key string) error
}

// MockDHTInterface wraps MockDHT to implement the DHT interface
type MockDHTInterface struct {
	mock *MockDHT
}

// NewMockDHTInterface creates a new MockDHTInterface
func NewMockDHTInterface() *MockDHTInterface {
	return &MockDHTInterface{
		mock: NewMockDHT(),
	}
}

// PutValue implements DHT interface
func (m *MockDHTInterface) PutValue(ctx context.Context, key string, value []byte) error {
	return m.mock.PutValue(ctx, key, value)
}

// GetValue implements DHT interface
func (m *MockDHTInterface) GetValue(ctx context.Context, key string) ([]byte, error) {
	return m.mock.GetValue(ctx, key)
}

// Provide implements DHT interface
func (m *MockDHTInterface) Provide(ctx context.Context, key string) error {
	return m.mock.Provide(ctx, key)
}

// FindProviders implements DHT interface
func (m *MockDHTInterface) FindProviders(ctx context.Context, key string, limit int) ([]peer.AddrInfo, error) {
	providers, err := m.mock.FindProviders(ctx, key, limit)
	if err != nil {
		return nil, err
	}
	
	// Convert string peer IDs to peer.AddrInfo
	result := make([]peer.AddrInfo, 0, len(providers))
	for _, providerStr := range providers {
		// For mock DHT, create minimal AddrInfo from string ID
		peerID, err := peer.Decode(providerStr)
		if err != nil {
			// If decode fails, skip this provider
			continue
		}
		result = append(result, peer.AddrInfo{
			ID: peerID,
		})
	}
	
	return result, nil
}

// GetStats implements DHT interface
func (m *MockDHTInterface) GetStats() DHTStats {
	return m.mock.GetStats()
}

// Expose underlying mock for testing
func (m *MockDHTInterface) Mock() *MockDHT {
	return m.mock
}

// Close implements a close method for MockDHTInterface
func (m *MockDHTInterface) Close() error {
	// Mock DHT doesn't need cleanup, return nil
	return nil
}