// apparmor.d - Full set of apparmor profiles
// Copyright (C) 2021-2024 Alexandre Pujol <alexandre@pujol.io>
// SPDX-License-Identifier: GPL-2.0-only

package cfg

import (
	"strings"

	"github.com/roddhjav/apparmor.d/pkg/util"
)

var Hide = `# This file is generated by "make", all edit will be lost.

/etc/apparmor.d/usr.bin.firefox
/etc/apparmor.d/usr.sbin.cups-browsed
/etc/apparmor.d/usr.sbin.cupsd
/etc/apparmor.d/usr.sbin.rsyslogd
`

type Flagger struct{}

func (f Flagger) Read(name string) map[string][]string {
	res := map[string][]string{}
	path := FlagDir.Join(name + ".flags")
	if !path.Exist() {
		return res
	}

	lines := util.MustReadFileAsLines(path)
	for _, line := range lines {
		manifest := strings.Split(line, " ")
		profile := manifest[0]
		flags := []string{}
		if len(manifest) > 1 {
			flags = strings.Split(manifest[1], ",")
		}
		res[profile] = flags
	}
	return res
}

type Ignorer struct{}

func (i Ignorer) Read(name string) []string {
	path := IgnoreDir.Join(name + ".ignore")
	if !path.Exist() {
		return []string{}
	}
	return util.MustReadFileAsLines(path)
}

type Overwriter struct {
	Enabled bool
}

// Get the list of upstream profiles to overwrite from dist/overwrite
func (o Overwriter) Get() []string {
	path := DistDir.Join("overwrite")
	if !path.Exist() {
		return []string{}
	}
	return util.MustReadFileAsLines(path)
}

// Overwrite upstream profile for APT: rename our profile & hide upstream
func (o Overwriter) Apt(files []string) {
	const ext = ".apparmor.d"
	file, err := DebianDir.Join("apparmor.d.hide").Append()
	if err != nil {
		panic(err)
	}
	for _, name := range files {
		origin := RootApparmord.Join(name)
		dest := RootApparmord.Join(name + ext)
		if err := origin.Rename(dest); err != nil {
			panic(err)
		}
		if _, err := file.WriteString("/etc/apparmor.d/" + name + "\n"); err != nil {
			panic(err)
		}
	}
}

// Clean the debian/apparmor.d.hide file
func (o Overwriter) AptClean() {
	path := DebianDir.Join("apparmor.d.hide")
	if err := path.WriteFile([]byte(Hide)); err != nil {
		panic(err)
	}
}
