// Copyright 2018 The Prometheus Authors
// 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 procfs

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"
)

// For the proc file format details,
// see https://elixir.bootlin.com/linux/v4.17/source/net/unix/af_unix.c#L2815
// and https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/net.h#L48.

// Constants for the various /proc/net/unix enumerations.
// TODO: match against x/sys/unix or similar?
const (
	netUnixTypeStream    = 1
	netUnixTypeDgram     = 2
	netUnixTypeSeqpacket = 5

	netUnixFlagDefault = 0
	netUnixFlagListen  = 1 << 16

	netUnixStateUnconnected  = 1
	netUnixStateConnecting   = 2
	netUnixStateConnected    = 3
	netUnixStateDisconnected = 4
)

// NetUNIXType is the type of the type field.
type NetUNIXType uint64

// NetUNIXFlags is the type of the flags field.
type NetUNIXFlags uint64

// NetUNIXState is the type of the state field.
type NetUNIXState uint64

// NetUNIXLine represents a line of /proc/net/unix.
type NetUNIXLine struct {
	KernelPtr string
	RefCount  uint64
	Protocol  uint64
	Flags     NetUNIXFlags
	Type      NetUNIXType
	State     NetUNIXState
	Inode     uint64
	Path      string
}

// NetUNIX holds the data read from /proc/net/unix.
type NetUNIX struct {
	Rows []*NetUNIXLine
}

// NetUNIX returns data read from /proc/net/unix.
func (fs FS) NetUNIX() (*NetUNIX, error) {
	return readNetUNIX(fs.proc.Path("net/unix"))
}

// readNetUNIX reads data in /proc/net/unix format from the specified file.
func readNetUNIX(file string) (*NetUNIX, error) {
	// This file could be quite large and a streaming read is desirable versus
	// reading the entire contents at once.
	f, err := os.Open(file)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	return parseNetUNIX(f)
}

// parseNetUNIX creates a NetUnix structure from the incoming stream.
func parseNetUNIX(r io.Reader) (*NetUNIX, error) {
	// Begin scanning by checking for the existence of Inode.
	s := bufio.NewScanner(r)
	s.Scan()

	// From the man page of proc(5), it does not contain an Inode field,
	// but in actually it exists. This code works for both cases.
	hasInode := strings.Contains(s.Text(), "Inode")

	// Expect a minimum number of fields, but Inode and Path are optional:
	// Num       RefCount Protocol Flags    Type St Inode Path
	minFields := 6
	if hasInode {
		minFields++
	}

	var nu NetUNIX
	for s.Scan() {
		line := s.Text()
		item, err := nu.parseLine(line, hasInode, minFields)
		if err != nil {
			return nil, fmt.Errorf("failed to parse /proc/net/unix data %q: %w", line, err)
		}

		nu.Rows = append(nu.Rows, item)
	}

	if err := s.Err(); err != nil {
		return nil, fmt.Errorf("failed to scan /proc/net/unix data: %w", err)
	}

	return &nu, nil
}

func (u *NetUNIX) parseLine(line string, hasInode bool, min int) (*NetUNIXLine, error) {
	fields := strings.Fields(line)

	l := len(fields)
	if l < min {
		return nil, fmt.Errorf("expected at least %d fields but got %d", min, l)
	}

	// Field offsets are as follows:
	// Num       RefCount Protocol Flags    Type St Inode Path

	kernelPtr := strings.TrimSuffix(fields[0], ":")

	users, err := u.parseUsers(fields[1])
	if err != nil {
		return nil, fmt.Errorf("failed to parse ref count %q: %w", fields[1], err)
	}

	flags, err := u.parseFlags(fields[3])
	if err != nil {
		return nil, fmt.Errorf("failed to parse flags %q: %w", fields[3], err)
	}

	typ, err := u.parseType(fields[4])
	if err != nil {
		return nil, fmt.Errorf("failed to parse type %q: %w", fields[4], err)
	}

	state, err := u.parseState(fields[5])
	if err != nil {
		return nil, fmt.Errorf("failed to parse state %q: %w", fields[5], err)
	}

	var inode uint64
	if hasInode {
		inode, err = u.parseInode(fields[6])
		if err != nil {
			return nil, fmt.Errorf("failed to parse inode %q: %w", fields[6], err)
		}
	}

	n := &NetUNIXLine{
		KernelPtr: kernelPtr,
		RefCount:  users,
		Type:      typ,
		Flags:     flags,
		State:     state,
		Inode:     inode,
	}

	// Path field is optional.
	if l > min {
		// Path occurs at either index 6 or 7 depending on whether inode is
		// already present.
		pathIdx := 7
		if !hasInode {
			pathIdx--
		}

		n.Path = fields[pathIdx]
	}

	return n, nil
}

func (u NetUNIX) parseUsers(s string) (uint64, error) {
	return strconv.ParseUint(s, 16, 32)
}

func (u NetUNIX) parseType(s string) (NetUNIXType, error) {
	typ, err := strconv.ParseUint(s, 16, 16)
	if err != nil {
		return 0, err
	}

	return NetUNIXType(typ), nil
}

func (u NetUNIX) parseFlags(s string) (NetUNIXFlags, error) {
	flags, err := strconv.ParseUint(s, 16, 32)
	if err != nil {
		return 0, err
	}

	return NetUNIXFlags(flags), nil
}

func (u NetUNIX) parseState(s string) (NetUNIXState, error) {
	st, err := strconv.ParseInt(s, 16, 8)
	if err != nil {
		return 0, err
	}

	return NetUNIXState(st), nil
}

func (u NetUNIX) parseInode(s string) (uint64, error) {
	return strconv.ParseUint(s, 10, 64)
}

func (t NetUNIXType) String() string {
	switch t {
	case netUnixTypeStream:
		return "stream"
	case netUnixTypeDgram:
		return "dgram"
	case netUnixTypeSeqpacket:
		return "seqpacket"
	}
	return "unknown"
}

func (f NetUNIXFlags) String() string {
	switch f {
	case netUnixFlagListen:
		return "listen"
	default:
		return "default"
	}
}

func (s NetUNIXState) String() string {
	switch s {
	case netUnixStateUnconnected:
		return "unconnected"
	case netUnixStateConnecting:
		return "connecting"
	case netUnixStateConnected:
		return "connected"
	case netUnixStateDisconnected:
		return "disconnected"
	}
	return "unknown"
}
