// 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 debug

import (
	"fmt"
	"net"
	"strings"
	"time"

	"v.io/v23/context"
	"v.io/v23/flow"
	"v.io/v23/naming"
	inaming "v.io/x/ref/runtime/internal/naming"
)

func init() {
	flow.RegisterProtocol("debug", &debug{})
}

// Filters give you the chance to add your own logic to flow.Conns
// that get created.  This is useful in tests.  For example you might
// want to modify all packets, print them out, or perhaps cause
// errors.
type Filter func(flow.Conn) flow.Conn

type filterKey struct{}

// WithFilter attaches a filter to the context.  Any connection
// accepted or dialed with the debug protocol using this context will
// be wrapped via a call to filter.
func WithFilter(ctx *context.T, filter Filter) *context.T {
	return context.WithValue(ctx, filterKey{}, filter)
}
func filter(ctx *context.T, c flow.Conn) flow.Conn {
	if f, ok := ctx.Value(filterKey{}).(Filter); ok {
		return f(c)
	}
	return c
}

func WrapName(name string) string {
	addr, suffix := naming.SplitAddressName(name)
	if addr == "" {
		return name
	}
	iep, err := inaming.NewEndpoint(addr)
	if err != nil {
		return name
	}
	iep.Protocol, iep.Address = WrapAddress(iep.Protocol, iep.Address)
	return naming.JoinAddressName(iep.String(), suffix)
}

func WrapAddress(protocol, address string) (string, string) {
	return "debug", protocol + "/" + address
}

type addr string

func (a addr) Network() string { return "debug" }
func (a addr) String() string  { return string(a) }

type conn struct {
	base flow.Conn
	addr addr
}

func (c *conn) LocalAddr() net.Addr                  { return c.addr }
func (c *conn) ReadMsg() ([]byte, error)             { return c.base.ReadMsg() }
func (c *conn) WriteMsg(data ...[]byte) (int, error) { return c.base.WriteMsg(data...) }
func (c *conn) Close() error                         { return c.base.Close() }
func (c *conn) UnsafeDisableEncryption() bool        { return true }

type listener struct {
	base  flow.Listener
	addr  addr
	debug *debug
}

func (l *listener) Accept(ctx *context.T) (flow.Conn, error) {
	c, err := l.base.Accept(ctx)
	if err != nil {
		return nil, err
	}
	return &conn{base: filter(ctx, c), addr: l.addr}, nil
}
func (l *listener) Addr() net.Addr { return l.addr }
func (l *listener) Close() error   { return l.base.Close() }

type debug struct{}

func (d *debug) Dial(ctx *context.T, network, address string, timeout time.Duration) (flow.Conn, error) {
	var base flow.Protocol
	if network, address, base = baseProtocol(address); base == nil {
		return nil, fmt.Errorf("could not find underlying protocol %q", network)
	}
	c, err := base.Dial(ctx, network, address, timeout)
	if err != nil {
		return nil, err
	}
	return &conn{base: filter(ctx, c), addr: addr(network + "/" + address)}, nil
}
func (d *debug) Listen(ctx *context.T, network, address string) (flow.Listener, error) {
	var base flow.Protocol
	if network, address, base = baseProtocol(address); base == nil {
		return nil, fmt.Errorf("could not find underlying protocol %q", network)
	}
	l, err := base.Listen(ctx, network, address)
	if err != nil {
		return nil, err
	}
	return &listener{base: l, addr: addr(l.Addr().Network() + "/" + l.Addr().String())}, nil
}
func (d *debug) Resolve(ctx *context.T, network, address string) (string, string, error) {
	return network, address, nil
}

func baseProtocol(in string) (network, address string, base flow.Protocol) {
	parts := strings.SplitN(in, "/", 2)
	if len(parts) == 2 {
		network, address = parts[0], parts[1]
	} else {
		network, address = "", parts[0]
	}
	base, names := flow.RegisteredProtocol(network)
	if network == "" && len(names) > 0 {
		network = names[0]
	}
	return network, address, base
}
