// Copyright 2020 The Monogon Project Authors.
//
// SPDX-License-Identifier: Apache-2.0
//
// 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.

// The reconciler ensures that a base set of K8s resources is always available
// in the cluster. These are necessary to ensure correct out-of-the-box
// functionality. All resources containing the
// metropolis.monogon.dev/builtin=true label are assumed to be managed by the
// reconciler.
// It currently does not revert modifications made by admins, it is  planned to
// create an admission plugin prohibiting such modifications to resources with
// the metropolis.monogon.dev/builtin label to deal with that problem. This
// would also solve a potential issue where you could delete resources just by
// adding the metropolis.monogon.dev/builtin=true label.
package reconciler

import (
	"context"
	"fmt"
	"time"

	meta "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"

	"source.monogon.dev/metropolis/pkg/supervisor"
)

// Sad workaround for all the pointer booleans in K8s specs
func True() *bool {
	val := true
	return &val
}
func False() *bool {
	val := false
	return &val
}

const (
	// BuiltinLabelKey is used as a k8s label to mark built-in objects (ie., managed by the reconciler)
	BuiltinLabelKey = "metropolis.monogon.dev/builtin"
	// BuiltinLabelValue is used as a k8s label value, under the BuiltinLabelKey key.
	BuiltinLabelValue = "true"
	// BuiltinRBACPrefix is used to prefix all built-in objects that are part of the rbac/v1 API (eg.
	// {Cluster,}Role{Binding,} objects). This corresponds to the colon-separated 'namespaces' notation used by
	// Kubernetes system (system:) objects.
	BuiltinRBACPrefix = "metropolis:"
)

// builtinLabels makes a kubernetes-compatible label dictionary (key->value) that is used to mark objects that are
// built-in into Metropolis (ie., managed by the reconciler). These are then subsequently retrieved by listBuiltins.
// The extra argument specifies what other labels are to be merged into the the labels dictionary, for convenience. If
// nil or empty, no extra labels will be applied.
func builtinLabels(extra map[string]string) map[string]string {
	l := map[string]string{
		BuiltinLabelKey: BuiltinLabelValue,
	}
	if extra != nil {
		for k, v := range extra {
			l[k] = v
		}
	}
	return l
}

// listBuiltins returns a k8s client ListOptions structure that allows to retrieve all objects that are built-in into
// Metropolis currently present in the API server (ie., ones that are to be managed by the reconciler). These are
// created by applying builtinLabels to their metadata labels.
var listBuiltins = meta.ListOptions{
	LabelSelector: fmt.Sprintf("%s=%s", BuiltinLabelKey, BuiltinLabelValue),
}

// builtinRBACName returns a name that is compatible with colon-delimited 'namespaced' objects, a la system:*.
// These names are to be used by all builtins created as part of the rbac/v1 Kubernetes API.
func builtinRBACName(name string) string {
	return BuiltinRBACPrefix + name
}

// resource is a type of resource to be managed by the reconciler. All builti-ins/reconciled objects must implement
// this interface to be managed correctly by the reconciler.
type resource interface {
	// List returns a list of names of objects current present on the target (ie. k8s API server).
	List(ctx context.Context) ([]string, error)
	// Create creates an object on the target. The el interface{} argument is the black box object returned by the
	// Expected() call.
	Create(ctx context.Context, el interface{}) error
	// Delete delete an object, by name, from the target.
	Delete(ctx context.Context, name string) error
	// Expected returns a map of all objects expected to be present on the target. The keys are names (which must
	// correspond to the names returned by List() and used by Delete(), and the values are blackboxes that will then
	// be passed to the Create() call if their corresponding key (name) does not exist on the target.
	Expected() map[string]interface{}
}

func allResources(clientSet kubernetes.Interface) map[string]resource {
	return map[string]resource{
		"psps":                resourcePodSecurityPolicies{clientSet},
		"clusterroles":        resourceClusterRoles{clientSet},
		"clusterrolebindings": resourceClusterRoleBindings{clientSet},
		"storageclasses":      resourceStorageClasses{clientSet},
		"csidrivers":          resourceCSIDrivers{clientSet},
		"runtimeclasses":      resourceRuntimeClasses{clientSet},
	}
}

func Run(clientSet kubernetes.Interface) supervisor.Runnable {
	return func(ctx context.Context) error {
		log := supervisor.Logger(ctx)
		resources := allResources(clientSet)
		t := time.NewTicker(10 * time.Second)
		reconcileAll := func() {
			for name, resource := range resources {
				if err := reconcile(ctx, resource); err != nil {
					log.Warningf("Failed to reconcile built-in resources %s: %v", name, err)
				}
			}
		}
		supervisor.Signal(ctx, supervisor.SignalHealthy)
		reconcileAll()
		for {
			select {
			case <-t.C:
				reconcileAll()
			case <-ctx.Done():
				return nil
			}
		}
	}
}

func reconcile(ctx context.Context, r resource) error {
	present, err := r.List(ctx)
	if err != nil {
		return err
	}
	presentSet := make(map[string]bool)
	for _, el := range present {
		presentSet[el] = true
	}
	expectedMap := r.Expected()
	for name, el := range expectedMap {
		if !presentSet[name] {
			if err := r.Create(ctx, el); err != nil {
				return err
			}
		}
	}
	for name, _ := range presentSet {
		if _, ok := expectedMap[name]; !ok {
			if err := r.Delete(ctx, name); err != nil {
				return err
			}
		}
	}
	return nil
}
