/**
# Copyright (c) 2024, HCUOpt CORPORATION.  All rights reserved.
**/

package discover

import (
	"path/filepath"

	"tags.cncf.io/container-device-interface/pkg/cdi"
)

var _ Discover = (*Hook)(nil)

// Devices returns an empty list of devices for a Hook discoverer.
func (h Hook) Devices() ([]Device, error) {
	return nil, nil
}

// Mounts returns an empty list of mounts for a Hook discoverer.
func (h Hook) Mounts() ([]Mount, error) {
	return nil, nil
}

// Hooks allows the Hook type to also implement the Discoverer interface.
// It returns a single hook
func (h Hook) Hooks() ([]Hook, error) {
	return []Hook{h}, nil
}

func (h Hook) AdditionalGIDs() ([]uint32, error) {
	return []uint32{}, nil
}

// CreateSymlinkHook creates a hook which creates a symlink from link -> target.
func CreateSymlinkHook(dtkCDIHookPath string, links []string) Hook {
	if len(links) == 0 {
		return Hook{}
	}

	var args []string
	for _, link := range links {
		args = append(args, "--link", link)
	}
	return CreateDtkCDIHook(
		dtkCDIHookPath,
		"create-symlinks",
		args...,
	)
}

func CreateTrackHook(dtkCDIHookPath string, containerId string) Hook {
	return CreateDtkTrackHook(
		dtkCDIHookPath,
		"dcu-tracker",
		"release",
		containerId,
	)
}

func CreateDtkTrackHook(path string, s string, s2 string, id string) Hook {
	return Hook{
		Lifecycle: cdi.PoststopHook,
		Path:      path,
		Args:      []string{"dtk-ctk", s, s2, id},
	}
}

// CreateDtkCDIHook creates a hook which invokes the DTK Container CLI hook subcommand.
func CreateDtkCDIHook(dtkCDIHookPath string, hookName string, additionalArgs ...string) Hook {
	return cdiHook(dtkCDIHookPath).Create(hookName, additionalArgs...)
}

type cdiHook string

func (c cdiHook) Create(name string, args ...string) Hook {
	return Hook{
		Lifecycle: cdi.CreateContainerHook,
		Path:      string(c),
		Args:      append(c.requiredArgs(name), args...),
	}
}
func (c cdiHook) requiredArgs(name string) []string {
	base := filepath.Base(string(c))
	if base == "dtk-ctk" {
		return []string{base, "hook", name}
	}
	return []string{base, name}
}
