// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package flow

import (
	"fmt"
	"sync"
	"time"

	"v.io/v23/context"
	"v.io/v23/naming"
)

// Protocol is the interface that protocols for use with vanadium RPCs must implement.
type Protocol interface {
	// Dial is the function used to create Conn objects given a
	// protocol-specific string representation of an address.
	// The returned Conn must also frame the connection.
	Dial(ctx *context.T, protocol, address string, timeout time.Duration) (Conn, error)
	// Resolve is the function used for protocol-specific address normalization.
	// e.g. the TCP resolve performs DNS resolution.
	Resolve(ctx *context.T, proctocol, address string) (string, string, error)
	// Listen is the function used to create Listener objects given a
	// protocol-specific string representation of the address a server will listen on.
	// The Conns returned from Listener must frame connections.
	Listen(ctx *context.T, protocol, address string) (Listener, error)
}

// RegisterProtocol makes available a Protocol to RegisteredProtocol.
// If the protocol represents other actual protocols, you need to specify all the
// actual protocols. E.g, "wsh" represents "tcp4", "tcp6", "ws4", and "ws6".
//
// Implementations of the Manager interface are expected to use this registry
// in order to expand the reach of the types of network protocols they can
// handle.
//
// Successive calls to RegisterProtocol replace the contents of a previous
// call to it and returns trues if a previous value was replaced, false otherwise.
func RegisterProtocol(protocol string, obj Protocol, p ...string) bool {
	// This is for handling the common case where protocol is a "singleton", to
	// make it easier to specify.
	if len(p) == 0 {
		p = []string{protocol}
	}
	registryLock.Lock()
	defer registryLock.Unlock()
	_, present := registry[protocol]
	registry[protocol] = registryEntry{obj, p}
	return present
}

// RegisterUnknownProtocol registers a Protocol for endpoints with
// no specified protocol.
//
// The desired protocol provided in the first argument will be passed to the
// Protocol methods as the actual protocol to use when dialing, resolving, or listening.
//
// The protocol itself must have already been registered before RegisterUnknownProtocol
// is called, otherwise we'll panic.
func RegisterUnknownProtocol(protocol string, obj Protocol) bool {
	var p []string
	registryLock.RLock()
	r, present := registry[protocol]
	if !present {
		panic(fmt.Sprintf("%s not registered", protocol))
	}
	p = r.p
	registryLock.RUnlock()
	return RegisterProtocol(naming.UnknownProtocol, wrappedProtocol{protocol, obj}, p...)
}

type wrappedProtocol struct {
	protocol string
	obj      Protocol
}

func (p wrappedProtocol) Dial(ctx *context.T, _, address string, timeout time.Duration) (Conn, error) {
	return p.obj.Dial(ctx, p.protocol, address, timeout)
}

func (p wrappedProtocol) Resolve(ctx *context.T, _, address string) (string, string, error) {
	return p.obj.Resolve(ctx, p.protocol, address)
}

func (p wrappedProtocol) Listen(ctx *context.T, _, address string) (Listener, error) {
	return p.obj.Listen(ctx, p.protocol, address)
}

// RegisteredProtocol returns the Protocol object registered with a
// previous call to RegisterProtocol.
func RegisteredProtocol(protocol string) (Protocol, []string) {
	registryLock.RLock()
	e := registry[protocol]
	registryLock.RUnlock()
	return e.obj, e.p
}

// RegisteredProtocols returns the list of protocols that have been previously
// registered using RegisterProtocol. The underlying implementation will
// support additional protocols such as those supported by the native RPC stack.
func RegisteredProtocols() []string {
	registryLock.RLock()
	defer registryLock.RUnlock()
	p := make([]string, 0, len(registry))
	for k, _ := range registry {
		p = append(p, k)
	}
	return p
}

type registryEntry struct {
	obj Protocol
	p   []string
}

var (
	registryLock sync.RWMutex
	registry     = make(map[string]registryEntry)
)
