// Copyright 2015 The Go 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 icmp

import (
	"net"
	"strings"

	"golang.org/x/net/internal/iana"
)

const (
	classInterfaceInfo = 2

	afiIPv4 = 1
	afiIPv6 = 2
)

const (
	attrMTU = 1 << iota
	attrName
	attrIPAddr
	attrIfIndex
)

// An InterfaceInfo represents interface and next-hop identification.
type InterfaceInfo struct {
	Class     int // extension object class number
	Type      int // extension object sub-type
	Interface *net.Interface
	Addr      *net.IPAddr
}

func (ifi *InterfaceInfo) nameLen() int {
	if len(ifi.Interface.Name) > 63 {
		return 64
	}
	l := 1 + len(ifi.Interface.Name)
	return (l + 3) &^ 3
}

func (ifi *InterfaceInfo) attrsAndLen(proto int) (attrs, l int) {
	l = 4
	if ifi.Interface != nil && ifi.Interface.Index > 0 {
		attrs |= attrIfIndex
		l += 4
		if len(ifi.Interface.Name) > 0 {
			attrs |= attrName
			l += ifi.nameLen()
		}
		if ifi.Interface.MTU > 0 {
			attrs |= attrMTU
			l += 4
		}
	}
	if ifi.Addr != nil {
		switch proto {
		case iana.ProtocolICMP:
			if ifi.Addr.IP.To4() != nil {
				attrs |= attrIPAddr
				l += 4 + net.IPv4len
			}
		case iana.ProtocolIPv6ICMP:
			if ifi.Addr.IP.To16() != nil && ifi.Addr.IP.To4() == nil {
				attrs |= attrIPAddr
				l += 4 + net.IPv6len
			}
		}
	}
	return
}

// Len implements the Len method of Extension interface.
func (ifi *InterfaceInfo) Len(proto int) int {
	_, l := ifi.attrsAndLen(proto)
	return l
}

// Marshal implements the Marshal method of Extension interface.
func (ifi *InterfaceInfo) Marshal(proto int) ([]byte, error) {
	attrs, l := ifi.attrsAndLen(proto)
	b := make([]byte, l)
	if err := ifi.marshal(proto, b, attrs, l); err != nil {
		return nil, err
	}
	return b, nil
}

func (ifi *InterfaceInfo) marshal(proto int, b []byte, attrs, l int) error {
	b[0], b[1] = byte(l>>8), byte(l)
	b[2], b[3] = classInterfaceInfo, byte(ifi.Type)
	for b = b[4:]; len(b) > 0 && attrs != 0; {
		switch {
		case attrs&attrIfIndex != 0:
			b = ifi.marshalIfIndex(proto, b)
			attrs &^= attrIfIndex
		case attrs&attrIPAddr != 0:
			b = ifi.marshalIPAddr(proto, b)
			attrs &^= attrIPAddr
		case attrs&attrName != 0:
			b = ifi.marshalName(proto, b)
			attrs &^= attrName
		case attrs&attrMTU != 0:
			b = ifi.marshalMTU(proto, b)
			attrs &^= attrMTU
		}
	}
	return nil
}

func (ifi *InterfaceInfo) marshalIfIndex(proto int, b []byte) []byte {
	b[0], b[1], b[2], b[3] = byte(ifi.Interface.Index>>24), byte(ifi.Interface.Index>>16), byte(ifi.Interface.Index>>8), byte(ifi.Interface.Index)
	return b[4:]
}

func (ifi *InterfaceInfo) parseIfIndex(b []byte) ([]byte, error) {
	if len(b) < 4 {
		return nil, errMessageTooShort
	}
	ifi.Interface.Index = int(b[0])<<24 | int(b[1])<<16 | int(b[2])<<8 | int(b[3])
	return b[4:], nil
}

func (ifi *InterfaceInfo) marshalIPAddr(proto int, b []byte) []byte {
	switch proto {
	case iana.ProtocolICMP:
		b[0], b[1] = byte(afiIPv4>>8), byte(afiIPv4)
		copy(b[4:4+net.IPv4len], ifi.Addr.IP.To4())
		b = b[4+net.IPv4len:]
	case iana.ProtocolIPv6ICMP:
		b[0], b[1] = byte(afiIPv6>>8), byte(afiIPv6)
		copy(b[4:4+net.IPv6len], ifi.Addr.IP.To16())
		b = b[4+net.IPv6len:]
	}
	return b
}

func (ifi *InterfaceInfo) parseIPAddr(b []byte) ([]byte, error) {
	if len(b) < 4 {
		return nil, errMessageTooShort
	}
	afi := int(b[0])<<8 | int(b[1])
	b = b[4:]
	switch afi {
	case afiIPv4:
		if len(b) < net.IPv4len {
			return nil, errMessageTooShort
		}
		ifi.Addr.IP = make(net.IP, net.IPv4len)
		copy(ifi.Addr.IP, b[:net.IPv4len])
		b = b[net.IPv4len:]
	case afiIPv6:
		if len(b) < net.IPv6len {
			return nil, errMessageTooShort
		}
		ifi.Addr.IP = make(net.IP, net.IPv6len)
		copy(ifi.Addr.IP, b[:net.IPv6len])
		b = b[net.IPv6len:]
	}
	return b, nil
}

func (ifi *InterfaceInfo) marshalName(proto int, b []byte) []byte {
	l := byte(ifi.nameLen())
	b[0] = l
	copy(b[1:], []byte(ifi.Interface.Name))
	return b[l:]
}

func (ifi *InterfaceInfo) parseName(b []byte) ([]byte, error) {
	if 4 > len(b) || len(b) < int(b[0]) {
		return nil, errMessageTooShort
	}
	l := int(b[0])
	if l%4 != 0 || 4 > l || l > 64 {
		return nil, errInvalidExtension
	}
	var name [63]byte
	copy(name[:], b[1:l])
	ifi.Interface.Name = strings.Trim(string(name[:]), "\000")
	return b[l:], nil
}

func (ifi *InterfaceInfo) marshalMTU(proto int, b []byte) []byte {
	b[0], b[1], b[2], b[3] = byte(ifi.Interface.MTU>>24), byte(ifi.Interface.MTU>>16), byte(ifi.Interface.MTU>>8), byte(ifi.Interface.MTU)
	return b[4:]
}

func (ifi *InterfaceInfo) parseMTU(b []byte) ([]byte, error) {
	if len(b) < 4 {
		return nil, errMessageTooShort
	}
	ifi.Interface.MTU = int(b[0])<<24 | int(b[1])<<16 | int(b[2])<<8 | int(b[3])
	return b[4:], nil
}

func parseInterfaceInfo(b []byte) (Extension, error) {
	ifi := &InterfaceInfo{
		Class: int(b[2]),
		Type:  int(b[3]),
	}
	if ifi.Type&(attrIfIndex|attrName|attrMTU) != 0 {
		ifi.Interface = &net.Interface{}
	}
	if ifi.Type&attrIPAddr != 0 {
		ifi.Addr = &net.IPAddr{}
	}
	attrs := ifi.Type & (attrIfIndex | attrIPAddr | attrName | attrMTU)
	for b = b[4:]; len(b) > 0 && attrs != 0; {
		var err error
		switch {
		case attrs&attrIfIndex != 0:
			b, err = ifi.parseIfIndex(b)
			attrs &^= attrIfIndex
		case attrs&attrIPAddr != 0:
			b, err = ifi.parseIPAddr(b)
			attrs &^= attrIPAddr
		case attrs&attrName != 0:
			b, err = ifi.parseName(b)
			attrs &^= attrName
		case attrs&attrMTU != 0:
			b, err = ifi.parseMTU(b)
			attrs &^= attrMTU
		}
		if err != nil {
			return nil, err
		}
	}
	if ifi.Interface != nil && ifi.Interface.Name != "" && ifi.Addr != nil && ifi.Addr.IP.To16() != nil && ifi.Addr.IP.To4() == nil {
		ifi.Addr.Zone = ifi.Interface.Name
	}
	return ifi, nil
}
