package libnmdc

import (
	"sync"
	"time"
)

type AutodetectProtocol struct {
	hc *HubConnection

	realProtoMut sync.Mutex
	realProto    Protocol
}

func NewAutodetectProtocol(hc *HubConnection) Protocol {
	proto := AutodetectProtocol{
		hc:        hc,
		realProto: nil,
	}

	go proto.timeout()

	return &proto
}

func (this *AutodetectProtocol) timeout() {
	time.Sleep(AUTODETECT_ADC_NMDC_TIMEOUT)

	this.realProtoMut.Lock()
	defer this.realProtoMut.Unlock()

	if this.realProto == nil {
		this.realProto = NewAdcProtocol(this.hc)
		this.hc.processEvent(HubEvent{EventType: EVENT_DEBUG_MESSAGE, Message: "Detected ADC protocol"})
	}
}

func (this *AutodetectProtocol) ProcessCommand(msg string) {
	this.realProtoMut.Lock()
	defer this.realProtoMut.Unlock()

	if this.realProto == nil {
		// We actually got some data using $ as the separator?
		// Upgrade to a full NMDC protocol
		this.realProto = NewNmdcProtocol(this.hc)
		this.hc.processEvent(HubEvent{EventType: EVENT_DEBUG_MESSAGE, Message: "Detected NMDC protocol"})
	}

	this.realProto.ProcessCommand(msg)
}

func (this *AutodetectProtocol) SayPublic(msg string) error {
	this.realProtoMut.Lock()
	defer this.realProtoMut.Unlock()

	if this.realProto == nil {
		this.realProto = NewNmdcProtocol(this.hc)
	}
	return this.realProto.SayPublic(msg)
}

func (this *AutodetectProtocol) SayPrivate(user, message string) error {
	this.realProtoMut.Lock()
	defer this.realProtoMut.Unlock()

	if this.realProto == nil {
		this.realProto = NewNmdcProtocol(this.hc)
	}
	return this.realProto.SayPrivate(user, message)
}

func (this *AutodetectProtocol) SayInfo() error {
	this.realProtoMut.Lock()
	defer this.realProtoMut.Unlock()

	if this.realProto == nil {
		this.realProto = NewNmdcProtocol(this.hc)
	}
	return this.realProto.SayInfo()
}

func (this *AutodetectProtocol) ProtoMessageSeparator() string {
	this.realProtoMut.Lock()
	defer this.realProtoMut.Unlock()

	if this.realProto == nil {
		return "|"
	}
	return this.realProto.ProtoMessageSeparator()
}
