// Local extensions to kube.upstream.libsonnet.

local kube = import "kube.upstream.libsonnet";

kube {
    ClusterIssuer(name): kube._Object("cert-manager.io/v1", "ClusterIssuer", name) {
        spec: error "spec must be defined",
    },
    Issuer(name): kube._Object("cert-manager.io/v1", "Issuer", name) {
        spec: error "spec must be defined",
    },
    Certificate(name): kube._Object("cert-manager.io/v1", "Certificate", name) {
        spec: error "spec must be defined",
    },
    # For use in PodSpec.volumes_
    CertificateVolume(certificate): {
        secret: { secretName: certificate.spec.secretName },
    },

    ValidatingWebhookConfiguration(name): kube._Object("admissionregistration.k8s.io/v1", "ValidatingWebhookConfiguration", name) {
        webhooks_:: error "webhooks_ must be defined",
        webhooks: kube.mapToNamedList(self.webhooks_),
    },

    # Add .Contain method to Namespaces, allowing for easy marking of particular
    # kube objects as contained in that namespace.
    Namespace(name): kube.Namespace(name) {
        Contain(o):: o {
            metadata+: {
                namespace: name,
            },
        },
    },

    // Remove deprecated `volume.beta.kubernetes.io/storage-class` annotation
    PersistentVolumeClaim(name): kube.PersistentVolumeClaim(name) {
        metadata+: { annotations: {} },
    },

    // Add `target` field
    Service(name): kube.Service(name) {
        // Deployment, Pod, DaemonSet, etc. that this Service is targeting.
        target:: error "service target must be defined",
        target_pod:: kube.podRef(self.target),
    },

    CephObjectStoreUser(name): kube._Object("ceph.rook.io/v1", "CephObjectStoreUser", name) {
        local user = self,
        spec: error "spec must be defined",

        // Name of the secret that contains the login data for this user.
        // This secret is created in the same namespace as the ceph cluster, so
        // unfortunately you can't really refer to it directly.
        // We should write some automation to copy these secrets over in a
        // secure way.
        secret_name:: "rook-ceph-object-user-%s-%s" % [user.spec.store, user.spec.displayName],
    },

    // Make OpenAPI v3 schema specification less painful.
    OpenAPI:: {
        local openapi = self,
        Validation(obj):: {
            openAPIV3Schema: obj.render,
        },

        Required(inner):: inner {
            required:: true,
        },

        renderable:: {
            required:: false,
            render:: {},
        },
        local renderable = self.renderable,

        lift(f, keys):: {
            [if f[k] != null then k]: f[k]
            for k in keys
        },
        local lift = self.lift,

        parametrized(type, keys=[]):: (
            local keysp = keys + [
                "description",
                "nullable",
                "x-kubernetes-preserve-unknown-fields",
            ];
            renderable {
                render:: lift(self, keysp) {
                    type: type,
                },
            } + {
                [k]: null
                for k in keysp
            }
        ),
        local parametrized = self.parametrized,

        Any:: renderable,
        Boolean:: parametrized("boolean"),
        Integer:: parametrized("integer", ["minimum", "maximum", "format"]),
        Number:: parametrized("number"),
        String:: parametrized("string", ["pattern"]),

        Dict:: renderable {
            local d = self,

            local requiredList = [
                k for k in std.filter(function(k) d[k].required, std.objectFields(d))
            ],

            render+: {
                properties: {
                    [k]: d[k].render
                    for k in std.objectFields(d)
                },
                [if std.length(requiredList) > 0 then 'required']: requiredList,
            },
        },
        Object(props={}):: parametrized("object") {
            local requiredList = [
                k for k in std.filter(function(k) props[k].required, std.objectFields(props))
            ],

            render+: {
                [if std.length(std.objectFields(props)) > 0 then "properties"]: {
                    [k]: props[k].render
                    for k in std.objectFields(props)
                },
                [if std.length(requiredList) > 0 then 'required']: requiredList,
            },
        },

        Array(items):: parametrized("array") {
            render+: {
                items: items.render,
            },
        },

        Enum(items):: parametrized("string") {
            render+: {
                enum: items,
            },
        },

        KubeAny(nullable=false):: self.Object() {
            [if nullable then "nullable"]: true,
            "x-kubernetes-preserve-unknown-fields": true,
        },
    },
}
