/*
 *------------------------------------------------------------------
 * Copyright (c) 2020 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *------------------------------------------------------------------
 */

// Package memif provides the implementation of shared memory interface (memif).
//
// Memif network interfaces communicate using UNIX domain socket. This socket
// must be first created using NewSocket(). Then interfaces can be added
// to this socket using NewInterface(). To start communication on each socket
// socket.StartPolling() must be called. socket.StopPolling() will stop
// the communication. When the interface changes link status Connected and
// Disconencted callbacks set in Arguments for each interface are called
// respectively. Once the interface is connected rx and tx queues can be
// aquired using interface.GetRxQueue() and interface.GetTxQueue().
// Packets can be transmitted by calling queue.ReadPacket() on rx queues and
// queue.WritePacket() on tx queues. If the interface is disconnected
// queue.ReadPacket() and queue.WritePacket() MUST not be called.
//
// Data transmission is backed by shared memory. The driver works in
// promiscuous mode only.
package memif

import (
	"container/list"
	"fmt"
	"os"
	"syscall"
)

const (
	DefaultSocketFilename   = "/run/vpp/memif.sock"
	DefaultNumQueuePairs    = 1
	DefaultLog2RingSize     = 10
	DefaultPacketBufferSize = 2048
)

const mfd_allow_sealing = 2
const sys_memfd_create = 319
const f_add_seals = 1033
const f_seal_shrink = 0x0002

const efd_nonblock = 04000

// ConnectedFunc is a callback called when an interface is connected
type ConnectedFunc func(i *Interface) error

// DisconnectedFunc is a callback called when an interface is disconnected
type DisconnectedFunc func(i *Interface) error

// MemoryConfig represents shared memory configuration
type MemoryConfig struct {
	NumQueuePairs    uint16 // number of queue pairs
	Log2RingSize     uint8  // ring size as log2
	PacketBufferSize uint32 // size of single packet buffer
}

// Arguments represent interface configuration
type Arguments struct {
	Id               uint32 // Interface identifier unique across socket. Used to identify peer interface when connecting
	IsMaster         bool   // Interface role master/slave
	Name             string
	Secret           [24]byte // optional parameter, secrets of the interfaces must match if they are to connect
	MemoryConfig     MemoryConfig
	ConnectedFunc    ConnectedFunc    // callback called when interface changes status to connected
	DisconnectedFunc DisconnectedFunc // callback called when interface changes status to disconnected
	PrivateData      interface{}      // private data used by client program
}

// memoryRegion represents a shared memory mapped file
type memoryRegion struct {
	data               []byte
	size               uint64
	fd                 int
	packetBufferOffset uint32
}

// Queue represents rx or tx queue
type Queue struct {
	ring        *ring
	i           *Interface
	lastHead    uint16
	lastTail    uint16
	interruptFd int
}

// Interface represents memif network interface
type Interface struct {
	args        Arguments
	run         MemoryConfig
	privateData interface{}
	listRef     *list.Element
	socket      *Socket
	cc          *controlChannel
	remoteName  string
	peerName    string
	regions     []memoryRegion
	txQueues    []Queue
	rxQueues    []Queue
}

// IsMaster returns true if the interfaces role is master, else returns false
func (i *Interface) IsMaster() bool {
	return i.args.IsMaster
}

// GetRemoteName returns the name of the application on which the peer
// interface exists
func (i *Interface) GetRemoteName() string {
	return i.remoteName
}

// GetPeerName returns peer interfaces name
func (i *Interface) GetPeerName() string {
	return i.peerName
}

// GetName returens interfaces name
func (i *Interface) GetName() string {
	return i.args.Name
}

// GetMemoryConfig returns interfaces active memory config.
// If interface is not connected the config is invalid.
func (i *Interface) GetMemoryConfig() MemoryConfig {
	return i.run
}

// GetRxQueue returns an rx queue specified by queue index
func (i *Interface) GetRxQueue(qid int) (*Queue, error) {
	if qid >= len(i.rxQueues) {
		return nil, fmt.Errorf("Invalid Queue index")
	}
	return &i.rxQueues[qid], nil
}

// GetRxQueue returns a tx queue specified by queue index
func (i *Interface) GetTxQueue(qid int) (*Queue, error) {
	if qid >= len(i.txQueues) {
		return nil, fmt.Errorf("Invalid Queue index")
	}
	return &i.txQueues[qid], nil
}

// GetEventFd returns queues interrupt event fd
func (q *Queue) GetEventFd() (int, error) {
	return q.interruptFd, nil
}

// GetFilename returns sockets filename
func (socket *Socket) GetFilename() string {
	return socket.filename
}

// close closes the queue
func (q *Queue) close() {
	syscall.Close(q.interruptFd)
}

// IsConnecting returns true if the interface is connecting
func (i *Interface) IsConnecting() bool {
	if i.cc != nil {
		return true
	}
	return false
}

// IsConnected returns true if the interface is connected
func (i *Interface) IsConnected() bool {
	if i.cc != nil && i.cc.isConnected {
		return true
	}
	return false
}

// Disconnect disconnects the interface
func (i *Interface) Disconnect() (err error) {
	if i.cc != nil {
		// close control and disconenct interface
		return i.cc.close(true, "Interface disconnected")
	}
	return nil
}

// disconnect finalizes interface disconnection
func (i *Interface) disconnect() (err error) {
	if i.cc == nil { // disconnected
		return nil
	}

	err = i.args.DisconnectedFunc(i)
	if err != nil {
		return fmt.Errorf("DisconnectedFunc: ", err)
	}

	for _, q := range i.txQueues {
		q.close()
	}
	i.txQueues = []Queue{}

	for _, q := range i.rxQueues {
		q.close()
	}
	i.rxQueues = []Queue{}

	// unmap regions
	for _, r := range i.regions {
		err = syscall.Munmap(r.data)
		if err != nil {
			return err
		}
		err = syscall.Close(r.fd)
		if err != nil {
			return err
		}
	}
	i.regions = nil
	i.cc = nil

	i.peerName = ""
	i.remoteName = ""

	return nil
}

// Delete deletes the interface
func (i *Interface) Delete() (err error) {
	i.Disconnect()

	// remove referance on socket
	i.socket.interfaceList.Remove(i.listRef)
	i = nil

	return nil
}

// GetSocket returns the socket the interface belongs to
func (i *Interface) GetSocket() *Socket {
	return i.socket
}

// GetPrivateDate returns interfaces private data
func (i *Interface) GetPrivateData() interface{} {
	return i.args.PrivateData
}

// GetId returns interfaces id
func (i *Interface) GetId() uint32 {
	return i.args.Id
}

// RoleToString returns 'Master' if isMaster os true, else returns 'Slave'
func RoleToString(isMaster bool) string {
	if isMaster {
		return "Master"
	}
	return "Slave"
}

// RequestConnection is used by slave interface to connect to a socket and
// create a control channel
func (i *Interface) RequestConnection() error {
	if i.IsMaster() {
		return fmt.Errorf("Only slave can request connection")
	}
	// create socket
	fd, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_SEQPACKET, 0)
	if err != nil {
		return fmt.Errorf("Failed to create UNIX domain socket: %v", err)
	}
	usa := &syscall.SockaddrUnix{Name: i.socket.filename}

	// Connect to listener socket
	err = syscall.Connect(fd, usa)
	if err != nil {
		return fmt.Errorf("Failed to connect socket %s : %v", i.socket.filename, err)
	}

	// Create control channel
	i.cc, err = i.socket.addControlChannel(fd, i)
	if err != nil {
		return fmt.Errorf("Failed to create control channel: %v", err)
	}

	return nil
}

// NewInterface returns a new memif network interface. When creating an interface
// it's id must be unique across socket with the exception of loopback interface
// in which case the id is the same but role differs
func (socket *Socket) NewInterface(args *Arguments) (*Interface, error) {
	var err error
	// make sure the ID is unique on this socket
	for elt := socket.interfaceList.Front(); elt != nil; elt = elt.Next() {
		i, ok := elt.Value.(*Interface)
		if ok {
			if i.args.Id == args.Id && i.args.IsMaster == args.IsMaster {
				return nil, fmt.Errorf("Interface with id %u role %s already exists on this socket", args.Id, RoleToString(args.IsMaster))
			}
		}
	}

	// copy interface configuration
	i := Interface{
		args: *args,
	}
	// set default values
	if i.args.MemoryConfig.NumQueuePairs == 0 {
		i.args.MemoryConfig.NumQueuePairs = DefaultNumQueuePairs
	}
	if i.args.MemoryConfig.Log2RingSize == 0 {
		i.args.MemoryConfig.Log2RingSize = DefaultLog2RingSize
	}
	if i.args.MemoryConfig.PacketBufferSize == 0 {
		i.args.MemoryConfig.PacketBufferSize = DefaultPacketBufferSize
	}

	i.socket = socket

	// append interface to the list
	i.listRef = socket.interfaceList.PushBack(&i)

	if i.args.IsMaster {
		if socket.listener == nil {
			err = socket.addListener()
			if err != nil {
				return nil, fmt.Errorf("Failed to create listener channel: %s", err)
			}
		}
	}

	return &i, nil
}

// eventFd returns an eventfd (SYS_EVENTFD2)
func eventFd() (efd int, err error) {
	u_efd, _, errno := syscall.Syscall(syscall.SYS_EVENTFD2, uintptr(0), uintptr(efd_nonblock), 0)
	if errno != 0 {
		return -1, os.NewSyscallError("eventfd", errno)
	}
	return int(u_efd), nil
}

// addRegions creates and adds a new memory region to the interface (slave only)
func (i *Interface) addRegion(hasPacketBuffers bool, hasRings bool) (err error) {
	var r memoryRegion

	if hasRings {
		r.packetBufferOffset = uint32((i.run.NumQueuePairs + i.run.NumQueuePairs) * (ringSize + descSize*(1<<i.run.Log2RingSize)))
	} else {
		r.packetBufferOffset = 0
	}

	if hasPacketBuffers {
		r.size = uint64(r.packetBufferOffset + i.run.PacketBufferSize*uint32(1<<i.run.Log2RingSize)*uint32(i.run.NumQueuePairs+i.run.NumQueuePairs))
	} else {
		r.size = uint64(r.packetBufferOffset)
	}

	r.fd, err = memfdCreate()
	if err != nil {
		return err
	}

	_, _, errno := syscall.Syscall(syscall.SYS_FCNTL, uintptr(r.fd), uintptr(f_add_seals), uintptr(f_seal_shrink))
	if errno != 0 {
		syscall.Close(r.fd)
		return fmt.Errorf("memfdCreate: %s", os.NewSyscallError("fcntl", errno))
	}

	err = syscall.Ftruncate(r.fd, int64(r.size))
	if err != nil {
		syscall.Close(r.fd)
		r.fd = -1
		return fmt.Errorf("memfdCreate: %s", err)
	}

	r.data, err = syscall.Mmap(r.fd, 0, int(r.size), syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED)
	if err != nil {
		return fmt.Errorf("addRegion: %s", err)
	}

	i.regions = append(i.regions, r)

	return nil
}

// initializeRegions initializes interfaces regions (slave only)
func (i *Interface) initializeRegions() (err error) {

	err = i.addRegion(true, true)
	if err != nil {
		return fmt.Errorf("initializeRegions: %s", err)
	}

	return nil
}

// initializeQueues initializes interfaces queues (slave only)
func (i *Interface) initializeQueues() (err error) {
	var q *Queue
	var desc descBuf
	var slot int

	desc = newDescBuf()
	desc.setFlags(0)
	desc.setRegion(0)
	desc.setLength(int(i.run.PacketBufferSize))

	for qid := 0; qid < int(i.run.NumQueuePairs); qid++ {
		/* TX */
		q = &Queue{
			ring:     i.newRing(0, ringTypeS2M, qid),
			lastHead: 0,
			lastTail: 0,
			i:        i,
		}
		q.ring.setCookie(cookie)
		q.ring.setFlags(1)
		q.interruptFd, err = eventFd()
		if err != nil {
			return err
		}
		q.putRing()
		i.txQueues = append(i.txQueues, *q)

		for j := 0; j < q.ring.size; j++ {
			slot = qid*q.ring.size + j
			desc.setOffset(int(i.regions[0].packetBufferOffset + uint32(slot)*i.run.PacketBufferSize))
			q.putDescBuf(slot, desc)
		}
	}
	for qid := 0; qid < int(i.run.NumQueuePairs); qid++ {
		/* RX */
		q = &Queue{
			ring:     i.newRing(0, ringTypeM2S, qid),
			lastHead: 0,
			lastTail: 0,
			i:        i,
		}
		q.ring.setCookie(cookie)
		q.ring.setFlags(1)
		q.interruptFd, err = eventFd()
		if err != nil {
			return err
		}
		q.putRing()
		i.rxQueues = append(i.rxQueues, *q)

		for j := 0; j < q.ring.size; j++ {
			slot = qid*q.ring.size + j
			desc.setOffset(int(i.regions[0].packetBufferOffset + uint32(slot)*i.run.PacketBufferSize))
			q.putDescBuf(slot, desc)
		}
	}

	return nil
}

// connect finalizes interface connection
func (i *Interface) connect() (err error) {
	for rid, _ := range i.regions {
		r := &i.regions[rid]
		if r.data == nil {
			r.data, err = syscall.Mmap(r.fd, 0, int(r.size), syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED)
			if err != nil {
				return fmt.Errorf("Mmap: %s", err)
			}
		}
	}

	for _, q := range i.txQueues {
		q.updateRing()

		if q.ring.getCookie() != cookie {
			return fmt.Errorf("Wrong cookie")
		}

		q.lastHead = 0
		q.lastTail = 0
	}

	for _, q := range i.rxQueues {
		q.updateRing()

		if q.ring.getCookie() != cookie {
			return fmt.Errorf("Wrong cookie")
		}

		q.lastHead = 0
		q.lastTail = 0
	}

	return i.args.ConnectedFunc(i)
}
