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

import (
	"errors"
	"fmt"
	"net"
	"regexp"
	"strconv"
	"strings"

	"v.io/v23/naming"
	"v.io/x/lib/metadata"
)

const (
	separator          = "@"
	suffix             = "@@"
	blessingsSeparator = ","
)

var (
	errInvalidEndpointString = errors.New("invalid endpoint string")
	hostportEP               = regexp.MustCompile("^(?:\\((.*)\\)@)?([^@]+)$")
)

// Network is the string returned by naming.Endpoint.Network implementations
// defined in this package.
const Network = "v23"

// Endpoint is a naming.Endpoint implementation used to convey RPC information.
type Endpoint struct {
	Protocol     string
	Address      string
	RID          naming.RoutingID
	Blessings    []string
	IsMountTable bool
	IsLeaf       bool
}

// NewEndpoint creates a new endpoint from a string as per naming.NewEndpoint
func NewEndpoint(input string) (*Endpoint, error) {
	ep := new(Endpoint)

	// We have to guess this is a mount table if we don't know.
	ep.IsMountTable = true

	// If the endpoint does not end in a @, it must be in [blessing@]host:port format.
	if parts := hostportEP.FindStringSubmatch(input); len(parts) > 0 {
		hostport := parts[len(parts)-1]
		var blessing string
		if len(parts) > 2 {
			blessing = parts[1]
		}
		err := ep.parseHostPort(blessing, hostport)
		return ep, err
	}
	// Trim the prefix and suffix and parse the rest.
	input = strings.TrimPrefix(strings.TrimSuffix(input, suffix), separator)
	parts := strings.Split(input, separator)
	version, err := strconv.ParseUint(parts[0], 10, 16)
	if err != nil {
		return nil, fmt.Errorf("invalid version: %v", err)
	}

	switch version {
	case 5:
		err = ep.parseV5(parts)
	default:
		err = errInvalidEndpointString
	}
	return ep, err
}

func (ep *Endpoint) parseHostPort(blessing, hostport string) error {
	// Could be in host:port format.
	if _, _, err := net.SplitHostPort(hostport); err != nil {
		return errInvalidEndpointString
	}
	ep.Protocol = naming.UnknownProtocol
	ep.Address = hostport
	ep.RID = naming.NullRoutingID
	if len(blessing) > 0 {
		ep.Blessings = []string{blessing}
	}
	return nil
}

func parseMountTableFlag(input string) (bool, bool, error) {
	switch len(input) {
	case 0:
		return true, false, nil
	case 1:
		switch f := input[0]; f {
		case 'l':
			return false, true, nil
		case 'm':
			return true, false, nil
		case 's':
			return false, false, nil
		default:
			return false, false, fmt.Errorf("%c is not one of 'l', 'm', or 's'", f)
		}
	}
	return false, false, fmt.Errorf("flag is either missing or too long")
}

func (ep *Endpoint) parseV5(parts []string) error {
	if len(parts) < 5 {
		return errInvalidEndpointString
	}

	ep.Protocol = parts[1]
	if len(ep.Protocol) == 0 {
		ep.Protocol = naming.UnknownProtocol
	}

	var ok bool
	if ep.Address, ok = naming.Unescape(parts[2]); !ok {
		return fmt.Errorf("invalid address: bad escape %s", parts[2])
	}
	if len(ep.Address) == 0 {
		ep.Address = net.JoinHostPort("", "0")
	}

	if err := ep.RID.FromString(parts[3]); err != nil {
		return fmt.Errorf("invalid routing id: %v", err)
	}

	var err error
	if ep.IsMountTable, ep.IsLeaf, err = parseMountTableFlag(parts[4]); err != nil {
		return fmt.Errorf("invalid mount table flag: %v", err)
	}
	// Join the remaining and re-split.
	if str := strings.Join(parts[5:], separator); len(str) > 0 {
		ep.Blessings = strings.Split(str, blessingsSeparator)
	}
	return nil
}

func (ep *Endpoint) RoutingID() naming.RoutingID {
	//nologcall
	return ep.RID
}
func (ep *Endpoint) Network() string {
	//nologcall
	return Network
}

func init() {
	metadata.Insert("v23.RPCEndpointVersion", fmt.Sprint(defaultVersion))
}

var defaultVersion = 5

func (ep *Endpoint) VersionedString(version int) string {
	// nologcall
	switch version {
	default:
		return ep.VersionedString(defaultVersion)
	case 5:
		mt := "s"
		switch {
		case ep.IsLeaf:
			mt = "l"
		case ep.IsMountTable:
			mt = "m"
		}
		blessings := strings.Join(ep.Blessings, blessingsSeparator)
		return fmt.Sprintf("@5@%s@%s@%s@%s@%s@@",
			ep.Protocol, naming.Escape(ep.Address, "@"), ep.RID, mt, blessings)
	}
}

func (ep *Endpoint) String() string {
	//nologcall
	return ep.VersionedString(defaultVersion)
}

func (ep *Endpoint) Name() string {
	//nologcall
	return naming.JoinAddressName(ep.String(), "")
}

func (ep *Endpoint) Addr() net.Addr {
	//nologcall
	return &addr{network: ep.Protocol, address: ep.Address}
}

func (ep *Endpoint) ServesMountTable() bool {
	//nologcall
	return ep.IsMountTable
}

func (ep *Endpoint) ServesLeaf() bool {
	//nologcall
	return ep.IsLeaf
}

func (ep *Endpoint) BlessingNames() []string {
	//nologcall
	return ep.Blessings
}

type addr struct {
	network, address string
}

func (a *addr) Network() string {
	return a.network
}

func (a *addr) String() string {
	return a.address
}
