package dns

import (
	"fmt"
	"net/netip"
	"net/url"

	"github.com/miekg/dns"

	dnsconfig "github.com/netbirdio/netbird/client/internal/dns/config"
	nbdns "github.com/netbirdio/netbird/dns"
	"github.com/netbirdio/netbird/route"
	"github.com/netbirdio/netbird/shared/management/domain"
)

// MockServer is the mock instance of a dns server
type MockServer struct {
	InitializeFunc         func() error
	StopFunc               func()
	UpdateDNSServerFunc    func(serial uint64, update nbdns.Config) error
	RegisterHandlerFunc    func(domain.List, dns.Handler, int)
	DeregisterHandlerFunc  func(domain.List, int)
	UpdateServerConfigFunc func(domains dnsconfig.ServerDomains) error
}

func (m *MockServer) RegisterHandler(domains domain.List, handler dns.Handler, priority int) {
	if m.RegisterHandlerFunc != nil {
		m.RegisterHandlerFunc(domains, handler, priority)
	}
}

func (m *MockServer) DeregisterHandler(domains domain.List, priority int) {
	if m.DeregisterHandlerFunc != nil {
		m.DeregisterHandlerFunc(domains, priority)
	}
}

// Initialize mock implementation of Initialize from Server interface
func (m *MockServer) Initialize() error {
	if m.InitializeFunc != nil {
		return m.InitializeFunc()
	}
	return nil
}

// Stop mock implementation of Stop from Server interface
func (m *MockServer) Stop() {
	if m.StopFunc != nil {
		m.StopFunc()
	}
}

func (m *MockServer) DnsIP() netip.Addr {
	return netip.MustParseAddr("100.10.254.255")
}

func (m *MockServer) OnUpdatedHostDNSServer(addrs []netip.AddrPort) {
	// TODO implement me
	panic("implement me")
}

// UpdateDNSServer mock implementation of UpdateDNSServer from Server interface
func (m *MockServer) UpdateDNSServer(serial uint64, update nbdns.Config) error {
	if m.UpdateDNSServerFunc != nil {
		return m.UpdateDNSServerFunc(serial, update)
	}
	return fmt.Errorf("method UpdateDNSServer is not implemented")
}

func (m *MockServer) SearchDomains() []string {
	return make([]string, 0)
}

func (m *MockServer) UpdateServerConfig(domains dnsconfig.ServerDomains) error {
	if m.UpdateServerConfigFunc != nil {
		return m.UpdateServerConfigFunc(domains)
	}
	return nil
}

func (m *MockServer) PopulateManagementDomain(mgmtURL *url.URL) error {
	return nil
}

// SetRouteSources mock implementation of SetRouteSources from Server interface
func (m *MockServer) SetRouteSources(selected, active func() route.HAMap) {
	// Mock implementation - no-op
}

// SetFirewall mock implementation of SetFirewall from Server interface
func (m *MockServer) SetFirewall(Firewall) {
	// Mock implementation - no-op
}

// BeginBatch mock implementation of BeginBatch from Server interface
func (m *MockServer) BeginBatch() {
	// Mock implementation - no-op
}

// EndBatch mock implementation of EndBatch from Server interface
func (m *MockServer) EndBatch() {
	// Mock implementation - no-op
}

// CancelBatch mock implementation of CancelBatch from Server interface
func (m *MockServer) CancelBatch() {
	// Mock implementation - no-op
}
