package kmod

import (
	"bufio"
	"bytes"
	"debug/elf"
	"errors"
	"fmt"
	"io"
	"strings"
)

// ModuleInfo contains Linux kernel module metadata. It maps keys to a list
// of values. For known keys accessor functions are provided.
type ModuleInfo map[string][]string

// Get returns the first value of the given key or an empty string if the key
// does not exist.
func (i ModuleInfo) Get(key string) string {
	if len(i[key]) > 0 {
		return i[key][0]
	}
	return ""
}

// Name returns the name of the module as defined in kbuild.
func (i ModuleInfo) Name() string {
	return i.Get("name")
}

// Authors returns the list of a authors of the module.
func (i ModuleInfo) Authors() []string {
	return i["author"]
}

// Description returns a human-readable description of the module or an empty
// string if it is not available.
func (i ModuleInfo) Description() string {
	return i.Get("description")
}

// GetDependencies returns a list of module names which need to be loaded
// before this one.
func (i ModuleInfo) GetDependencies() []string {
	if len(i["depends"]) == 1 && i["depends"][0] == "" {
		return nil
	}
	return i["depends"]
}

type OptionalDependencies struct {
	// Pre contains a list of module names to be optionally loaded before the
	// module itself.
	Pre []string
	// Post contains a list of module names to be optionally loaded after the
	// module itself.
	Post []string
}

// GetOptionalDependencies returns a set of modules which are recommended to
// be loaded before and after this module. These are optional, but enhance
// the functionality of this module.
func (i ModuleInfo) GetOptionalDependencies() OptionalDependencies {
	var out OptionalDependencies
	for _, s := range i["softdep"] {
		tokens := strings.Fields(s)
		const (
			MODE_IDLE = 0
			MODE_PRE  = 1
			MODE_POST = 2
		)
		var state int = MODE_IDLE
		for _, token := range tokens {
			switch token {
			case "pre:":
				state = MODE_PRE
			case "post:":
				state = MODE_POST
			default:
				switch state {
				case MODE_PRE:
					out.Pre = append(out.Pre, token)
				case MODE_POST:
					out.Post = append(out.Post, token)
				default:
				}
			}
		}
	}
	return out
}

// Aliases returns a list of match expressions for matching devices handled
// by this module. Every returned string consists of a literal as well as '*'
// wildcards matching one or more characters. These should be matched against
// the kobject MODALIAS field or the modalias sysfs file.
func (i ModuleInfo) Aliases() []string {
	return i["alias"]
}

// Firmware returns a list of firmware file paths required by this module.
// These paths are usually relative to the root of a linux-firmware install
// unless the firmware is non-redistributable.
func (i ModuleInfo) Firmware() []string {
	return i["firmware"]
}

// License returns the licenses use of this module is governed by. For mainline
// modules, the list of valid license strings is documented in the kernel's
// Documentation/process/license-rules.rst file under the `MODULE_LICENSE`
// section.
func (i ModuleInfo) Licenses() []string {
	return i["license"]
}

// IsInTree returns true if the module was built in the Linux source tree and
// not externally. This does not necessarily mean that the module is in the
// mainline kernel.
func (i ModuleInfo) IsInTree() bool {
	return i.Get("intree") == "Y"
}

// vermagic and retpoline are intentionally not exposed here, if you need them
// you should know how to get them out of the map yourself as AFAIK these
// are not a stable interface and most programs should not process them.

func nullByteSplit(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}
	if i := bytes.IndexByte(data, 0x00); i >= 0 {
		return i + 1, bytes.TrimLeft(data[0:i], "\x00"), nil
	}
	if atEOF {
		return len(data), data, nil
	}
	return 0, nil, nil
}

// GetModuleInfo looks for a ".modinfo" section in the passed ELF Linux kernel
// module and parses it into a ModuleInfo structure.
func GetModuleInfo(e *elf.File) (ModuleInfo, error) {
	for _, section := range e.Sections {
		if section.Name == ".modinfo" {
			out := make(ModuleInfo)
			s := bufio.NewScanner(io.NewSectionReader(section, 0, int64(section.Size)))
			s.Split(nullByteSplit)

			for s.Scan() {
				// Format is <key>=<value>
				key, value, ok := bytes.Cut(s.Bytes(), []byte("="))
				if !ok {
					continue
				}
				keyStr := string(key)
				out[keyStr] = append(out[keyStr], string(value))
			}
			return out, nil
		}
	}
	return nil, errors.New("no .modinfo section found")
}

// GetBuiltinModulesInfo parses all modinfo structures for builtin modules from
// a modinfo file (modules.builtin.modinfo).
func GetBuiltinModulesInfo(f io.Reader) ([]ModuleInfo, error) {
	var out []ModuleInfo
	s := bufio.NewScanner(f)
	s.Split(nullByteSplit)

	currModule := make(ModuleInfo)
	for s.Scan() {
		if s.Err() != nil {
			return nil, fmt.Errorf("failed scanning for next token: %w", s.Err())
		}
		// Format is <module>.<key>=<value>
		modName, entry, ok := bytes.Cut(s.Bytes(), []byte{'.'})
		if !ok {
			continue
		}
		if string(modName) != currModule.Name() {
			if currModule.Name() != "" {
				out = append(out, currModule)
			}
			currModule = make(ModuleInfo)
			currModule["name"] = []string{string(modName)}
		}
		key, value, ok := bytes.Cut(entry, []byte("="))
		if !ok {
			continue
		}
		keyStr := string(key)
		currModule[keyStr] = append(currModule[keyStr], string(value))
	}
	if currModule.Name() != "" {
		out = append(out, currModule)
	}
	seenModNames := make(map[string]bool)
	for _, m := range out {
		if seenModNames[m.Name()] {
			return nil, fmt.Errorf("duplicate/out-of-order module metadata for module %q", m)
		}
		seenModNames[m.Name()] = true
	}
	return out, nil
}
