// Generic library of Kubernetes objects (https://github.com/bitnami-labs/kube-libsonnet)
//
// Objects in this file follow the regular Kubernetes API object
// schema with two exceptions:
//
// ## Optional helpers
//
// A few objects have defaults or additional "helper" hidden
// (double-colon) fields that will help with common situations.  For
// example, `Service.target_pod` generates suitable `selector` and
// `ports` blocks for the common case of a single-pod/single-port
// service.  If for some reason you don't want the helper, just
// provide explicit values for the regular Kubernetes fields that the
// helper *would* have generated, and the helper logic will be
// ignored.
//
// ## The Underscore Convention:
//
// Various constructs in the Kubernetes API use JSON arrays to
// represent unordered sets or named key/value maps.  This is
// particularly annoying with jsonnet since we want to use jsonnet's
// powerful object merge operation with these constructs.
//
// To combat this, this library attempts to provide more "jsonnet
// native" variants of these arrays in alternative hidden fields that
// end with an underscore.  For example, the `env_` block in
// `Container`:
// ```
// kube.Container("foo") {
//   env_: { FOO: "bar" },
// }
// ```
// ... produces the expected `container.env` JSON array:
// ```
// {
//   "env": [
//     { "name": "FOO", "value": "bar" }
//   ]
// }
// ```
//
// If you are confused by the underscore versions, or don't want them
// in your situation then just ignore them and set the regular
// non-underscore field as usual.
//
//
// ## TODO
//
// TODO: Expand this to include all API objects.
//
// Should probably fill out all the defaults here too, so jsonnet can
// reference them.  In addition, jsonnet validation is more useful
// (client-side, and gives better line information).

{
  // In case you may want/need to skip assertions for speed reasons (rather big configmaps/etc),
  // load the library with e.g.
  //   local kube = (import "lib/kube.libsonnet") { _assert:: false };
  _assert:: true,

  // resource contructors will use kinds/versions/fields compatible at least with version:
  minKubeVersion: {
    major: 1,
    minor: 14,
    version: "%s.%s" % [self.major, self.minor],
  },

  // Returns array of values from given object.  Does not include hidden fields.
  objectValues(o):: [o[field] for field in std.objectFields(o)],

  // Returns array of [key, value] pairs from given object.  Does not include hidden fields.
  objectItems(o):: [[k, o[k]] for k in std.objectFields(o)],

  // Replace all occurrences of `_` with `-`.
  hyphenate(s):: std.join("-", std.split(s, "_")),

  // Convert an octal (as a string) to number,
  parseOctal(s):: (
    local len = std.length(s);
    local leading = std.substr(s, 0, len - 1);
    local last = std.parseInt(std.substr(s, len - 1, 1));
    assert (!$._assert) || last < 8 : "found '%s' digit >= 8" % [last];
    last + (if len > 1 then 8 * $.parseOctal(leading) else 0)
  ),

  // Convert {foo: {a: b}} to [{name: foo, a: b}]
  mapToNamedList(o):: [{ name: $.hyphenate(n) } + o[n] for n in std.objectFields(o)],

  // Return object containing only these fields elements
  filterMapByFields(o, fields): { [field]: o[field] for field in std.setInter(std.objectFields(o), fields) },

  // Convert from SI unit suffixes to regular number
  siToNum(n):: (
    local convert =
      if std.endsWith(n, "m") then [1, 0.001]
      else if std.endsWith(n, "K") then [1, 1e3]
      else if std.endsWith(n, "M") then [1, 1e6]
      else if std.endsWith(n, "G") then [1, 1e9]
      else if std.endsWith(n, "T") then [1, 1e12]
      else if std.endsWith(n, "P") then [1, 1e15]
      else if std.endsWith(n, "E") then [1, 1e18]
      else if std.endsWith(n, "Ki") then [2, std.pow(2, 10)]
      else if std.endsWith(n, "Mi") then [2, std.pow(2, 20)]
      else if std.endsWith(n, "Gi") then [2, std.pow(2, 30)]
      else if std.endsWith(n, "Ti") then [2, std.pow(2, 40)]
      else if std.endsWith(n, "Pi") then [2, std.pow(2, 50)]
      else if std.endsWith(n, "Ei") then [2, std.pow(2, 60)]
      else error "Unknown numerical suffix in " + n;
    local n_len = std.length(n);
    std.parseInt(std.substr(n, 0, n_len - convert[0])) * convert[1]
  ),

  local remap(v, start, end, newstart) =
    if v >= start && v <= end then v - start + newstart else v,
  local remapChar(c, start, end, newstart) =
    std.char(remap(
      std.codepoint(c), std.codepoint(start), std.codepoint(end), std.codepoint(newstart)
    )),
  toLower(s):: (
    std.join("", [remapChar(c, "A", "Z", "a") for c in std.stringChars(s)])
  ),
  toUpper(s):: (
    std.join("", [remapChar(c, "a", "z", "A") for c in std.stringChars(s)])
  ),

  boolXor(x, y):: ((if x then 1 else 0) + (if y then 1 else 0) == 1),

  _Object(apiVersion, kind, name):: {
    local this = self,
    apiVersion: apiVersion,
    kind: kind,
    metadata: {
      name: name,
      labels: { name: std.join("-", std.split(this.metadata.name, ":")) },
      annotations: {},
    },
  },

  List(): {
    apiVersion: "v1",
    kind: "List",
    items_:: {},
    items: $.objectValues(self.items_),
  },

  Namespace(name): $._Object("v1", "Namespace", name) {
  },

  Endpoints(name): $._Object("v1", "Endpoints", name) {
    Ip(addr):: { ip: addr },
    Port(p):: { port: p },

    subsets: [],
  },

  Service(name): $._Object("v1", "Service", name) {
    local service = self,

    target_pod:: error "service target_pod required",
    port:: self.target_pod.spec.containers[0].ports[0].containerPort,

    // Helpers that format host:port in various ways
    host:: "%s.%s.svc" % [self.metadata.name, self.metadata.namespace],
    host_colon_port:: "%s:%s" % [self.host, self.spec.ports[0].port],
    http_url:: "http://%s/" % self.host_colon_port,
    proxy_urlpath:: "/api/v1/proxy/namespaces/%s/services/%s/" % [
      self.metadata.namespace,
      self.metadata.name,
    ],
    // Useful in Ingress rules
    name_port:: {
      serviceName: service.metadata.name,
      servicePort: service.spec.ports[0].port,
    },

    spec: {
      selector: service.target_pod.metadata.labels,
      ports: [
        {
          port: service.port,
          name: service.target_pod.spec.containers[0].ports[0].name,
          targetPort: service.target_pod.spec.containers[0].ports[0].containerPort,
        },
      ],
      type: "ClusterIP",
    },
  },

  PersistentVolume(name): $._Object("v1", "PersistentVolume", name) {
    spec: {},
  },

  // TODO: This is a terrible name
  PersistentVolumeClaimVolume(pvc): {
    persistentVolumeClaim: { claimName: pvc.metadata.name },
  },

  StorageClass(name): $._Object("storage.k8s.io/v1beta1", "StorageClass", name) {
    provisioner: error "provisioner required",
  },

  PersistentVolumeClaim(name): $._Object("v1", "PersistentVolumeClaim", name) {
    local pvc = self,

    storageClass:: null,
    storage:: error "storage required",

    metadata+: if pvc.storageClass != null then {
      annotations+: {
        "volume.beta.kubernetes.io/storage-class": pvc.storageClass,
      },
    } else {},

    spec: {
      resources: {
        requests: {
          storage: pvc.storage,
        },
      },
      accessModes: ["ReadWriteOnce"],
      [if pvc.storageClass != null then "storageClassName"]: pvc.storageClass,
    },
  },

  Container(name): {
    name: name,
    image: error "container image value required",
    imagePullPolicy: if std.endsWith(self.image, ":latest") then "Always" else "IfNotPresent",

    envList(map):: [
      if std.type(map[x]) == "object"
      then {
        name: x,
        valueFrom: map[x],
      } else {
        // Let `null` value stay as such (vs string-ified)
        name: x,
        value: if map[x] == null then null else std.toString(map[x]),
      }
      for x in std.objectFields(map)
    ],

    env_:: {},
    env: self.envList(self.env_),

    args_:: {},
    args: ["--%s=%s" % kv for kv in $.objectItems(self.args_)],

    ports_:: {},
    ports: $.mapToNamedList(self.ports_),

    volumeMounts_:: {},
    volumeMounts: $.mapToNamedList(self.volumeMounts_),

    stdin: false,
    tty: false,
    assert (!$._assert) || (!self.tty || self.stdin) : "tty=true requires stdin=true",
  },

  PodDisruptionBudget(name): $._Object("policy/v1beta1", "PodDisruptionBudget", name) {
    local this = self,
    target_pod:: error "target_pod required",
    spec: {
      assert (!$._assert) || $.boolXor(
        std.objectHas(self, "minAvailable"),
        std.objectHas(self, "maxUnavailable")
      ) : "PDB '%s': exactly one of minAvailable/maxUnavailable required" % name,
      selector: {
        matchLabels: this.target_pod.metadata.labels,
      },
    },
  },

  Pod(name): $._Object("v1", "Pod", name) {
    spec: $.PodSpec,
  },

  PodSpec: {
    // The 'first' container is used in various defaults in k8s.
    local container_names = std.objectFields(self.containers_),
    default_container:: if std.length(container_names) > 1 then "default" else container_names[0],
    containers_:: {},

    local container_names_ordered = [self.default_container] + [n for n in container_names if n != self.default_container],
    containers: (
      assert (!$._assert) || std.length(self.containers_) > 0 : "Pod must have at least one container (via containers_ map)";
      [{ name: $.hyphenate(name) } + self.containers_[name] for name in container_names_ordered if self.containers_[name] != null]
    ),

    // Note initContainers are inherently ordered, and using this
    // named object will lose that ordering.  If order matters, then
    // manipulate `initContainers` directly (perhaps
    // appending/prepending to `super.initContainers` to mix+match
    // both approaches)
    initContainers_:: {},
    initContainers: [{ name: $.hyphenate(name) } + self.initContainers_[name] for name in std.objectFields(self.initContainers_) if self.initContainers_[name] != null],

    volumes_:: {},
    volumes: $.mapToNamedList(self.volumes_),

    imagePullSecrets: [],

    terminationGracePeriodSeconds: 30,

    assert (!$._assert) || std.length(self.containers) > 0 : "Pod must have at least one container (via containers array)",

    // Return an array of pod's ports numbers
    ports(proto):: [
      p.containerPort
      for p in std.flattenArrays([
        c.ports
        for c in self.containers
      ])
      if (
        (!(std.objectHas(p, "protocol")) && proto == "TCP")
        ||
        ((std.objectHas(p, "protocol")) && p.protocol == proto)
      )
    ],

  },

  EmptyDirVolume(): {
    emptyDir: {},
  },

  HostPathVolume(path, type=""): {
    hostPath: { path: path, type: type },
  },

  GitRepoVolume(repository, revision): {
    gitRepo: {
      repository: repository,

      // "master" is possible, but should be avoided for production
      revision: revision,
    },
  },

  SecretVolume(secret): {
    secret: { secretName: secret.metadata.name },
  },

  ConfigMapVolume(configmap): {
    configMap: { name: configmap.metadata.name },
  },

  ConfigMap(name): $._Object("v1", "ConfigMap", name) {
    data: {},

    // I keep thinking data values can be any JSON type.  This check
    // will remind me that they must be strings :(
    local nonstrings = [
      k
      for k in std.objectFields(self.data)
      if std.type(self.data[k]) != "string"
    ],
    assert (!$._assert) || std.length(nonstrings) == 0 : "data contains non-string values: %s" % [nonstrings],
  },

  // subtype of EnvVarSource
  ConfigMapRef(configmap, key): {
    assert (!$._assert) || std.objectHas(configmap.data, key) : "ConfigMap '%s' doesn't have '%s' field in configmap.data" % [configmap.metadata.name, key],
    configMapKeyRef: {
      name: configmap.metadata.name,
      key: key,
    },
  },

  Secret(name): $._Object("v1", "Secret", name) {
    local secret = self,

    type: "Opaque",
    data_:: {},
    data: { [k]: std.base64(secret.data_[k]) for k in std.objectFields(secret.data_) },
  },

  // subtype of EnvVarSource
  SecretKeyRef(secret, key): {
    assert (!$._assert) || std.objectHas(secret.data, key) : "Secret '%s' doesn't have '%s' field in secret.data" % [secret.metadata.name, key],
    secretKeyRef: {
      name: secret.metadata.name,
      key: key,
    },
  },

  // subtype of EnvVarSource
  FieldRef(key): {
    fieldRef: {
      apiVersion: "v1",
      fieldPath: key,
    },
  },

  // subtype of EnvVarSource
  ResourceFieldRef(key, divisor="1"): {
    resourceFieldRef: {
      resource: key,
      divisor: std.toString(divisor),
    },
  },

  Deployment(name): $._Object("apps/v1", "Deployment", name) {
    local deployment = self,

    spec: {
      template: {
        spec: $.PodSpec,
        metadata: {
          labels: deployment.metadata.labels,
          annotations: {},
        },
      },

      selector: {
        matchLabels: deployment.spec.template.metadata.labels,
      },

      strategy: {
        type: "RollingUpdate",

        local pvcs = [
          v
          for v in deployment.spec.template.spec.volumes
          if std.objectHas(v, "persistentVolumeClaim")
        ],
        local is_stateless = std.length(pvcs) == 0,

        // Apps trying to maintain a majority quorum or similar will
        // want to tune these carefully.
        // NB: Upstream default is surge=1 unavail=1
        rollingUpdate: if is_stateless then {
          maxSurge: "25%",  // rounds up
          maxUnavailable: "25%",  // rounds down
        } else {
          // Poor-man's StatelessSet.  Useful mostly with replicas=1.
          maxSurge: 0,
          maxUnavailable: 1,
        },
      },

      // NB: Upstream default is 0
      minReadySeconds: 30,

      // NB: Regular k8s default is to keep all revisions
      revisionHistoryLimit: 10,

      replicas: 1,
    },
  },

  CrossVersionObjectReference(target): {
    apiVersion: target.apiVersion,
    kind: target.kind,
    name: target.metadata.name,
  },

  HorizontalPodAutoscaler(name): $._Object("autoscaling/v1", "HorizontalPodAutoscaler", name) {
    local hpa = self,

    target:: error "target required",

    spec: {
      scaleTargetRef: $.CrossVersionObjectReference(hpa.target),

      minReplicas: hpa.target.spec.replicas,
      maxReplicas: error "maxReplicas required",

      assert (!$._assert) || self.maxReplicas >= self.minReplicas,
    },
  },

  StatefulSet(name): $._Object("apps/v1", "StatefulSet", name) {
    local sset = self,

    spec: {
      serviceName: name,

      updateStrategy: {
        type: "RollingUpdate",
        rollingUpdate: {
          partition: 0,
        },
      },

      template: {
        spec: $.PodSpec,
        metadata: {
          labels: sset.metadata.labels,
          annotations: {},
        },
      },

      selector: {
        matchLabels: sset.spec.template.metadata.labels,
      },

      volumeClaimTemplates_:: {},
      volumeClaimTemplates: [
        // StatefulSet is overly fussy about "changes" (even when
        // they're no-ops).
        // In particular annotations={} is apparently a "change",
        // since the comparison is ignorant of defaults.
        std.prune($.PersistentVolumeClaim($.hyphenate(kv[0])) + { apiVersion:: null, kind:: null } + kv[1])
        for kv in $.objectItems(self.volumeClaimTemplates_)
      ],

      replicas: 1,
      # TODO(github.com/bitnami-labs/kube-libsonnet/pull/66): update from
      # upstream when merged
      # assert (!$._assert) || self.replicas >= 1,
    },
  },

  Job(name): $._Object("batch/v1", "Job", name) {
    local job = self,

    spec: $.JobSpec {
      template+: {
        metadata+: {
          labels: job.metadata.labels,
        },
      },
    },
  },

  CronJob(name): $._Object("batch/v1beta1", "CronJob", name) {
    local cronjob = self,

    spec: {
      jobTemplate: {
        spec: $.JobSpec {
          template+: {
            metadata+: {
              labels: cronjob.metadata.labels,
            },
          },
        },
      },
      schedule: error "Need to provide spec.schedule",
      successfulJobsHistoryLimit: 10,
      failedJobsHistoryLimit: 20,
      // NB: upstream concurrencyPolicy default is "Allow"
      concurrencyPolicy: "Forbid",
    },
  },

  JobSpec: {
    local this = self,

    template: {
      spec: $.PodSpec {
        restartPolicy: "OnFailure",
      },
    },
    completions: 1,
    parallelism: 1,
  },

  DaemonSet(name): $._Object("apps/v1", "DaemonSet", name) {
    local ds = self,
    spec: {
      updateStrategy: {
        type: "RollingUpdate",
        rollingUpdate: {
          maxUnavailable: 1,
        },
      },
      template: {
        metadata: {
          labels: ds.metadata.labels,
          annotations: {},
        },
        spec: $.PodSpec,
      },

      selector: {
        matchLabels: ds.spec.template.metadata.labels,
      },
    },
  },

  Ingress(name): $._Object("networking.k8s.io/v1beta1", "Ingress", name) {
    spec: {},

    local rel_paths = [
      p.path
      for r in self.spec.rules
      for p in r.http.paths
      if std.objectHas(p, "path") && !std.startsWith(p.path, "/")
    ],
    assert (!$._assert) || std.length(rel_paths) == 0 : "paths must be absolute: " + rel_paths,
  },

  ThirdPartyResource(name): $._Object("extensions/v1beta1", "ThirdPartyResource", name) {
    versions_:: [],
    versions: [{ name: n } for n in self.versions_],
  },

  CustomResourceDefinition(group, version, kind): {
    local this = self,
    apiVersion: "apiextensions.k8s.io/v1beta1",
    kind: "CustomResourceDefinition",
    metadata+: {
      name: this.spec.names.plural + "." + this.spec.group,
    },
    spec: {
      scope: "Namespaced",
      group: group,
      version: version,
      names: {
        kind: kind,
        singular: $.toLower(self.kind),
        plural: self.singular + "s",
        listKind: self.kind + "List",
      },
    },
  },

  ServiceAccount(name): $._Object("v1", "ServiceAccount", name) {
  },

  Role(name): $._Object("rbac.authorization.k8s.io/v1", "Role", name) {
    rules: [],
  },

  ClusterRole(name): $.Role(name) {
    kind: "ClusterRole",
  },

  Group(name): {
    kind: "Group",
    name: name,
    apiGroup: "rbac.authorization.k8s.io",
  },

  User(name): {
    kind: "User",
    name: name,
    apiGroup: "rbac.authorization.k8s.io",
  },

  RoleBinding(name): $._Object("rbac.authorization.k8s.io/v1", "RoleBinding", name) {
    local rb = self,

    subjects_:: [],
    subjects: [{
      kind: o.kind,
      namespace: o.metadata.namespace,
      name: o.metadata.name,
    } for o in self.subjects_],

    roleRef_:: error "roleRef is required",
    roleRef: {
      apiGroup: "rbac.authorization.k8s.io",
      kind: rb.roleRef_.kind,
      name: rb.roleRef_.metadata.name,
    },
  },

  ClusterRoleBinding(name): $.RoleBinding(name) {
    kind: "ClusterRoleBinding",
  },

  // NB: encryptedData can be imported into a SealedSecret as follows:
  // kubectl get secret ... -ojson mysec | kubeseal | jq -r .spec.encryptedData > sealedsecret.json
  //   encryptedData: std.parseJson(importstr "sealedsecret.json")
  SealedSecret(name): $._Object("bitnami.com/v1alpha1", "SealedSecret", name) {
    spec: {
      encryptedData: {},
    },
    assert (!$._assert) || std.length(std.objectFields(self.spec.encryptedData)) != 0 : "SealedSecret '%s' has empty encryptedData field" % name,
  },

  // NB: helper method to access several Kubernetes objects podRef,
  // used below to extract its labels
  podRef(obj):: ({
                   Pod: obj,
                   Deployment: obj.spec.template,
                   StatefulSet: obj.spec.template,
                   DaemonSet: obj.spec.template,
                   Job: obj.spec.template,
                   CronJob: obj.spec.jobTemplate.spec.template,
                 }[obj.kind]),

  // NB: return a { podSelector: ... } ready to use for e.g. NSPs (see below)
  // pod labels can be optionally filtered by their label name 2nd array arg
  podLabelsSelector(obj, filter=null):: {
    podSelector: std.prune({
      matchLabels:
        if filter != null then $.filterMapByFields($.podRef(obj).metadata.labels, filter)
        else $.podRef(obj).metadata.labels,
    }),
  },

  // NB: Returns an array as [{ port: num, protocol: "PROTO" }, {...}, ... ]
  // Need to split TCP, UDP logic to be able to dedup each set of protocol ports
  podsPorts(obj_list):: std.flattenArrays([
    [
      { port: port, protocol: protocol }
      for port in std.set(
        std.flattenArrays([$.podRef(obj).spec.ports(protocol) for obj in obj_list])
      )
    ]
    for protocol in ["TCP", "UDP"]
  ]),

  // NB: most of the "helper" stuff comes from above (podLabelsSelector, podsPorts),
  // NetworkPolicy returned object will have "Ingress", "Egress" policyTypes auto-set
  // based on populated spec.ingress or spec.egress
  // See tests/test-simple-validate.jsonnet for example(s).
  NetworkPolicy(name): $._Object("networking.k8s.io/v1", "NetworkPolicy", name) {
    local networkpolicy = self,
    spec: {
      policyTypes: std.prune([
        if networkpolicy.spec.ingress != [] then "Ingress" else null,
        if networkpolicy.spec.egress != [] then "Egress" else null,
      ]),
      ingress: $.objectValues(self.ingress_),
      ingress_:: {},
      egress: $.objectValues(self.egress_),
      egress_:: {},
      podSelector: {},
    },
  },

  VerticalPodAutoscaler(name):: $._Object("autoscaling.k8s.io/v1beta2", "VerticalPodAutoscaler", name) {
    local vpa = self,

    target:: error "target required",

    spec: {
      targetRef: $.CrossVersionObjectReference(vpa.target),

      updatePolicy: {
        updateMode: "Auto",
      },
    },
  },
  // Helper function to ease VPA creation as e.g.:
  // foo_vpa:: kube.createVPAFor($.foo_deploy)
  createVPAFor(target, mode="Auto"):: $.VerticalPodAutoscaler(target.metadata.name) {
    target:: target,

    metadata+: {
      namespace: target.metadata.namespace,
      labels+: target.metadata.labels,
    },
    spec+: {
      updatePolicy+: {
        updateMode: mode,
      },
    },
  },
}
