package main

import (
	"fmt"
	"io"
	"os"
	"slices"
)

type NetworkPolicyGenerrator struct {
	config          *Config
	policyTemplates *PolicyTemplates
}

func (g NetworkPolicyGenerrator) GenerateNamespace(writer io.Writer, namespace *Namespace) error {
	fmt.Fprintf(os.Stderr, "Namespace %s\n", namespace.Name)

	templates := g.policyTemplates.NamespaceTemplates("netpol", namespace.Capabilities)

	for _, template := range templates {
		err := template.Execute(writer, &namespace)
		if err != nil {
			return fmt.Errorf("Error using template %s: %w", template.Name(), err)
		}
	}
	return nil
}

func (g NetworkPolicyGenerrator) GenerateCommunicationRule(
	writer io.Writer,
	app *Application,
	ingress *Ingress,
	egress *Egress) error {

	if len(ingress.Applications)+
		len(ingress.Networks)+
		len(egress.Applications)+
		len(egress.Networks) > 0 {
		// non-trivial regular network policy

		tmpl := g.policyTemplates.ApplicationTemplate("netpol")
		if tmpl == nil {
			return fmt.Errorf("Could not find policy template for 'netpol'")
		}
		err := tmpl.Execute(writer, map[string]any{
			"app":     app,
			"ingress": ingress,
			"egress":  egress,
			"labels": map[string]string{
				"policy-generator": "1",
			},
		})
		if err != nil {
			return err
		}
	}

	allPredefined := make(map[string]bool)
	for _, pre := range ingress.Predefined {
		allPredefined[pre] = true
	}
	for _, pre := range egress.Predefined {
		allPredefined[pre] = true
	}

	for predefined, _ := range allPredefined {
		tmpl := g.policyTemplates.PredefineApplicationPolicyTemplate("netpol", predefined)
		if tmpl == nil {
			return fmt.Errorf("Could not find predefined template for netpol/%s", predefined)
		}
		err := tmpl.Execute(writer, map[string]any{
			"app":     app,
			"ingress": slices.Contains(ingress.Predefined, predefined),
			"egress":  slices.Contains(egress.Predefined, predefined),
			"labels": map[string]string{
				"policy-generator": "1",
			},
		})
		if err != nil {
			return err
		}
	}

	return nil
}