// 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"
)

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 := naming.ParseEndpoint(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, []string{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
}
