use async_trait::async_trait;
use log::error;
use non_blank_string_rs::NonBlankString;
use serde::Serialize;
use std::str::FromStr;

use crate::{
    data::{Id, Version},
    interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome},
    inventory::Inventory,
    modules::helm::chart::{HelmChartScore, HelmRepository},
    score::Score,
    topology::{HelmCommand, K8sclient, Topology},
};

use super::ArgoApplication;

#[derive(Debug, Serialize, Clone)]
pub struct ArgoHelmScore {
    pub namespace: String,
    pub openshift: bool,
    pub domain: String,
    pub argo_apps: Vec<ArgoApplication>,
}

impl<T: Topology + HelmCommand + K8sclient> Score<T> for ArgoHelmScore {
    fn create_interpret(&self) -> Box<dyn crate::interpret::Interpret<T>> {
        let helm_score = argo_helm_chart_score(&self.namespace, self.openshift, &self.domain);
        Box::new(ArgoInterpret {
            score: helm_score,
            argo_apps: self.argo_apps.clone(),
        })
    }

    fn name(&self) -> String {
        "ArgoHelmScore".to_string()
    }
}

#[derive(Debug)]
pub struct ArgoInterpret {
    score: HelmChartScore,
    argo_apps: Vec<ArgoApplication>,
}

#[async_trait]
impl<T: Topology + K8sclient + HelmCommand> Interpret<T> for ArgoInterpret {
    async fn execute(
        &self,
        inventory: &Inventory,
        topology: &T,
    ) -> Result<Outcome, InterpretError> {
        error!("Uncomment below, only disabled for debugging");
        self.score
            .create_interpret()
            .execute(inventory, topology)
            .await?;

        let k8s_client = topology.k8s_client().await?;
        k8s_client
            .apply_yaml_many(&self.argo_apps.iter().map(|a| a.to_yaml()).collect(), None)
            .await
            .unwrap();
        Ok(Outcome::success(format!(
            "Successfully installed ArgoCD and {} Applications",
            self.argo_apps.len()
        )))
    }

    fn get_name(&self) -> InterpretName {
        InterpretName::ArgoCD
    }

    fn get_version(&self) -> Version {
        todo!()
    }

    fn get_status(&self) -> InterpretStatus {
        todo!()
    }

    fn get_children(&self) -> Vec<Id> {
        todo!()
    }
}

pub fn argo_helm_chart_score(namespace: &str, openshift: bool, domain: &str) -> HelmChartScore {
    let values = format!(
        r#"
# -- Create aggregated roles that extend existing cluster roles to interact with argo-cd resources
## Ref: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#aggregated-clusterroles
createAggregateRoles: false
# -- Create cluster roles for cluster-wide installation.
## Used when you manage applications in the same cluster where Argo CD runs
createClusterRoles: true

openshift:
  # -- enables using arbitrary uid for argo repo server
  enabled: {openshift}

## Custom resource configuration
crds:
  # -- Install and upgrade CRDs
  install: true
  # -- Keep CRDs on chart uninstall
  keep: true
  # -- Annotations to be added to all CRDs
  annotations: {{}}
  # -- Addtional labels to be added to all CRDs
  additionalLabels: {{}}

## Globally shared configuration
global:
  # -- Default domain used by all components
  ## Used for ingresses, certificates, SSO, notifications, etc.
  domain: {domain}

  # -- Runtime class name for all components
  runtimeClassName: ""

  # -- Common labels for the all resources
  additionalLabels: {{}}
    # app: argo-cd

  # -- Number of old deployment ReplicaSets to retain. The rest will be garbage collected.
  revisionHistoryLimit: 3

  # Default image used by all components
  image:
    # -- If defined, a repository applied to all Argo CD deployments
    repository: quay.io/argoproj/argocd
    # -- Overrides the global Argo CD image tag whose default is the chart appVersion
    tag: ""
    # -- If defined, a imagePullPolicy applied to all Argo CD deployments
    imagePullPolicy: IfNotPresent

  # -- Secrets with credentials to pull images from a private registry
  imagePullSecrets: []

  # Default logging options used by all components
  logging:
    # -- Set the global logging format. Either: `text` or `json`
    format: text
    # -- Set the global logging level. One of: `debug`, `info`, `warn` or `error`
    level: info


## Argo Configs
configs:
  # General Argo CD configuration. Any values you put under `.configs.cm` are passed to argocd-cm ConfigMap.
  ## Ref: https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/argocd-cm.yaml
  cm:
    # -- Create the argocd-cm configmap for [declarative setup]
    create: true

    # -- Enable local admin user
    ## Ref: https://argo-cd.readthedocs.io/en/latest/faq/#how-to-disable-admin-user
    admin.enabled: true

    # -- Timeout to discover if a new manifests version got published to the repository
    timeout.reconciliation: 180s

    # -- Timeout to refresh application data as well as target manifests cache
    timeout.hard.reconciliation: 0s


  # Argo CD configuration parameters
  ## Ref: https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/argocd-cmd-params-cm.yaml
  params:
    # -- Create the argocd-cmd-params-cm configmap
    # If false, it is expected the configmap will be created by something else.
    create: true


    # -- Enables [Applications in any namespace]
    ## List of additional namespaces where applications may be created in and reconciled from.
    ## The namespace where Argo CD is installed to will always be allowed.
    ## Set comma-separated list. (e.g. app-team-one, app-team-two)
    application.namespaces: ""


  # Argo CD RBAC policy configuration
  ## Ref: https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/rbac.md
  rbac:
    # -- Create the argocd-rbac-cm configmap with ([Argo CD RBAC policy]) definitions.
    # If false, it is expected the configmap will be created by something else.
    # Argo CD will not work if there is no configmap created with the name above.
    create: true

    # -- Annotations to be added to argocd-rbac-cm configmap
    annotations: {{}}

    # -- The name of the default role which Argo CD will falls back to, when authorizing API requests (optional).
    # If omitted or empty, users may be still be able to login, but will see no apps, projects, etc...
    policy.default: ''

    # -- File containing user-defined policies and role definitions.
    # @default -- `''` (See [values.yaml])
    policy.csv: ''
    # Policy rules are in the form:
    #  p, subject, resource, action, object, effect
    # Role definitions and bindings are in the form:
    #  g, subject, inherited-subject
    # policy.csv: |
    #   p, role:org-admin, applications, *, */*, allow
    #   p, role:org-admin, clusters, get, *, allow
    #   p, role:org-admin, repositories, *, *, allow
    #   p, role:org-admin, logs, get, *, allow
    #   p, role:org-admin, exec, create, */*, allow
    #   g, your-github-org:your-team, role:org-admin

    # -- OIDC scopes to examine during rbac enforcement (in addition to `sub` scope).
    # The scope value can be a string, or a list of strings.
    scopes: "[groups]"

    # -- Matcher function for Casbin, `glob` for glob matcher and `regex` for regex matcher.
    policy.matchMode: "glob"

  # GnuPG public keys for commit verification
  ## Ref: https://argo-cd.readthedocs.io/en/stable/user-guide/gpg-verification/
  gpg:
    # -- Annotations to be added to argocd-gpg-keys-cm configmap
    annotations: {{}}

    # -- [GnuPG] public keys to add to the keyring
    # @default -- `{{}}` (See [values.yaml])
    ## Note: Public keys should be exported with `gpg --export --armor <KEY>`
    keys: {{}}
      # 4AEE18F83AFDEB23: |
      #   -----BEGIN PGP PUBLIC KEY BLOCK-----
      #   ...
      #   -----END PGP PUBLIC KEY BLOCK-----

  # SSH known hosts for Git repositories
  ## Ref: https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/#ssh-known-host-public-keys
  ssh:
    # -- Specifies if the argocd-ssh-known-hosts-cm configmap should be created by Helm.
    create: true

    # -- Annotations to be added to argocd-ssh-known-hosts-cm configmap
    annotations: {{}}

    # -- Known hosts to be added to the known host list by default.
    # @default -- See [values.yaml]
    knownHosts: |
      [ssh.github.com]:443 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
      [ssh.github.com]:443 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
      [ssh.github.com]:443 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=
      bitbucket.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIQmuzMBuKdWeF4+a2sjSSpBK0iqitSQ+5BM9KhpexuGt20JpTVM7u5BDZngncgrqDMbWdxMWWOGtZ9UgbqgZE=
      bitbucket.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIazEu89wgQZ4bqs3d63QSMzYVa0MuJ2e2gKTKqu+UUO
      bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=
      github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
      github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
      github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=
      gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
      gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
      gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9
      ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H
      vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H

    # -- Additional known hosts for private repositories
    extraHosts: ''

  # Repository TLS certificates
  # Ref: https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/#repositories-using-self-signed-tls-certificates-or-are-signed-by-custom-ca
  tls:
    # -- Annotations to be added to argocd-tls-certs-cm configmap
    annotations: {{}}

    # -- TLS certificates for Git repositories
    # @default -- `{{}}` (See [values.yaml])
    certificates: {{}}
      # server.example.com: |
      #   -----BEGIN CERTIFICATE-----
      #   ...
      #   -----END CERTIFICATE-----

    # -- Specifies if the argocd-tls-certs-cm configmap should be created by Helm.
    create: true

  # -- Repositories list to be used by applications
  ## Creates a secret for each key/value specified below to create repositories
  ## Note: the last example in the list would use a repository credential template, configured under "configs.credentialTemplates".
  repositories: {{}}
    # istio-helm-repo:
    #   url: https://storage.googleapis.com/istio-prerelease/daily-build/master-latest-daily/charts
    #   name: istio.io
    #   type: helm
    # private-helm-repo:
    #   url: https://my-private-chart-repo.internal
    #   name: private-repo
    #   type: helm
    #   password: my-password
    #   username: my-username
    # private-repo:
    #   url: https://github.com/argoproj/private-repo

  # -- Annotations to be added to `configs.repositories` Secret
  repositoriesAnnotations: {{}}

  # Argo CD sensitive data
  # Ref: https://argo-cd.readthedocs.io/en/stable/operator-manual/user-management/#sensitive-data-and-sso-client-secrets
  secret:
    # -- Create the argocd-secret
    createSecret: true



## Application controller
controller:
  # -- Application controller name string
  name: application-controller

  # -- The number of application controller pods to run.
  # Additional replicas will cause sharding of managed clusters across number of replicas.
  ## With dynamic cluster distribution turned on, sharding of the clusters will gracefully
  ## rebalance if the number of replica's changes or one becomes unhealthy. (alpha)
  replicas: 1


  # -- Maximum number of controller revisions that will be maintained in StatefulSet history
  revisionHistoryLimit: 5

  # -- Resource limits and requests for the application controller pods
  resources: {{}}
  #  limits:
  #    cpu: 500m
  #    memory: 512Mi
  #  requests:
  #    cpu: 250m
  #    memory: 256Mi

  # Application controller container ports
  containerPorts:
    # -- Metrics container port
    metrics: 8082

  serviceAccount:
    # -- Create a service account for the application controller
    create: true
    # -- Service account name
    name: argocd-application-controller
    # -- Annotations applied to created service account
    annotations: {{}}
    # -- Labels applied to created service account
    labels: {{}}
    # -- Automount API credentials for the Service Account
    automountServiceAccountToken: true

  ## Application controller metrics configuration
  metrics:
    # -- Deploy metrics service
    enabled: true
    # -- Prometheus ServiceMonitor scrapeTimeout. If empty, Prometheus uses the global scrape timeout unless it is less than the target's scrape interval value in which the latter is used.
    scrapeTimeout: ""
    applicationLabels:
      # -- Enables additional labels in argocd_app_labels metric
      enabled: false
      # -- Additional labels
      labels: []
    service:
      # -- Metrics service type
      type: ClusterIP
      # -- Metrics service clusterIP. `None` makes a "headless service" (no virtual IP)
      clusterIP: ""
      # -- Metrics service annotations
      annotations: {{}}
      # -- Metrics service labels
      labels: {{}}
      # -- Metrics service port
      servicePort: 8082
      # -- Metrics service port name
      portName: http-metrics
    serviceMonitor:
      # -- Enable a prometheus ServiceMonitor
      enabled: true
      # -- Prometheus ServiceMonitor interval
      interval: 30s
      # -- When true, honorLabels preserves the metric’s labels when they collide with the target’s labels.
      honorLabels: false
      # -- Prometheus [RelabelConfigs] to apply to samples before scraping
      relabelings: []
      # -- Prometheus [MetricRelabelConfigs] to apply to samples before ingestion
      metricRelabelings: []
      # -- Prometheus ServiceMonitor selector
      selector: {{}}
        # prometheus: kube-prometheus

      # -- Prometheus ServiceMonitor scheme
      scheme: ""
      # -- Prometheus ServiceMonitor tlsConfig
      tlsConfig: {{}}
      # -- Prometheus ServiceMonitor namespace
      namespace: "" # "monitoring"
      # -- Prometheus ServiceMonitor labels
      additionalLabels: {{}}
      # -- Prometheus ServiceMonitor annotations
      annotations: {{}}
    rules:
      # -- Deploy a PrometheusRule for the application controller
      enabled: false
      # -- PrometheusRule namespace
      namespace: "" # "monitoring"
      # -- PrometheusRule selector
      selector: {{}}
        # prometheus: kube-prometheus

      # -- PrometheusRule labels
      additionalLabels: {{}}
      # -- PrometheusRule annotations
      annotations: {{}}

      # -- PrometheusRule.Spec for the application controller
      spec: []


## Dex
dex:
  # -- Enable dex
  enabled: false

## Redis
redis:
  # -- Enable redis
  enabled: true
  # -- Redis name
  name: redis

  ## Redis image
  image:
    # -- Redis repository
    repository: ecr-public.aws.com/docker/library/redis
    # -- Redis tag
    ## Do not upgrade to >= 7.4.0, otherwise you are no longer using an open source version of Redis
    tag: 7.2.8-alpine
    # -- Redis image pull policy
    # @default -- `""` (defaults to global.image.imagePullPolicy)
    imagePullPolicy: ""

  ## Prometheus redis-exporter sidecar
  exporter:
    # -- Enable Prometheus redis-exporter sidecar
    enabled: true
    # -- Environment variables to pass to the Redis exporter
    env: []
    ## Prometheus redis-exporter image
    image:
      # -- Repository to use for the redis-exporter
      repository: ghcr.io/oliver006/redis_exporter
      # -- Tag to use for the redis-exporter
      tag: v1.74.0
      # -- Image pull policy for the redis-exporter
      # @default -- `""` (defaults to global.image.imagePullPolicy)
      imagePullPolicy: ""


    ## Probes for Redis exporter (optional)
    ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
    readinessProbe:
      # -- Enable Kubernetes liveness probe for Redis exporter (optional)
      enabled: false
      # -- Number of seconds after the container has started before [probe] is initiated
      initialDelaySeconds: 30
      # -- How often (in seconds) to perform the [probe]
      periodSeconds: 15
      # -- Number of seconds after which the [probe] times out
      timeoutSeconds: 15
      # -- Minimum consecutive successes for the [probe] to be considered successful after having failed
      successThreshold: 1
      # -- Minimum consecutive failures for the [probe] to be considered failed after having succeeded
      failureThreshold: 5
    livenessProbe:
      # -- Enable Kubernetes liveness probe for Redis exporter
      enabled: false
      # -- Number of seconds after the container has started before [probe] is initiated
      initialDelaySeconds: 30
      # -- How often (in seconds) to perform the [probe]
      periodSeconds: 15
      # -- Number of seconds after which the [probe] times out
      timeoutSeconds: 15
      # -- Minimum consecutive successes for the [probe] to be considered successful after having failed
      successThreshold: 1
      # -- Minimum consecutive failures for the [probe] to be considered failed after having succeeded
      failureThreshold: 5

    # -- Resource limits and requests for redis-exporter sidecar
    resources:
      limits:
        cpu: 50m
        memory: 64Mi
      requests:
        cpu: 10m
        memory: 32Mi


  ## Probes for Redis server (optional)
  ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
  readinessProbe:
    # -- Enable Kubernetes liveness probe for Redis server
    enabled: false
    # -- Number of seconds after the container has started before [probe] is initiated
    initialDelaySeconds: 30
    # -- How often (in seconds) to perform the [probe]
    periodSeconds: 15
    # -- Number of seconds after which the [probe] times out
    timeoutSeconds: 15
    # -- Minimum consecutive successes for the [probe] to be considered successful after having failed
    successThreshold: 1
    # -- Minimum consecutive failures for the [probe] to be considered failed after having succeeded
    failureThreshold: 5
  livenessProbe:
    # -- Enable Kubernetes liveness probe for Redis server
    enabled: false
    # -- Number of seconds after the container has started before [probe] is initiated
    initialDelaySeconds: 30
    # -- How often (in seconds) to perform the [probe]
    periodSeconds: 15
    # -- Number of seconds after which the [probe] times out
    timeoutSeconds: 15
    # -- Minimum consecutive successes for the [probe] to be considered successful after having failed
    successThreshold: 1
    # -- Minimum consecutive failures for the [probe] to be considered failed after having succeeded
    failureThreshold: 5

  # -- Resource limits and requests for redis
  resources:
    limits:
      cpu: 200m
      memory: 128Mi
    requests:
      cpu: 100m
      memory: 64Mi



  metrics:
    # -- Deploy metrics service
    enabled: true

    # Redis metrics service configuration
    service:
      # -- Metrics service type
      type: ClusterIP
      # -- Metrics service clusterIP. `None` makes a "headless service" (no virtual IP)
      clusterIP: None
      # -- Metrics service annotations
      annotations: {{}}
      # -- Metrics service labels
      labels: {{}}
      # -- Metrics service port
      servicePort: 9121
      # -- Metrics service port name
      portName: http-metrics

    serviceMonitor:
      # -- Enable a prometheus ServiceMonitor
      enabled: true
      # -- Interval at which metrics should be scraped
      interval: 30s
      # -- When true, honorLabels preserves the metric’s labels when they collide with the target’s labels.
      honorLabels: false
      # -- Prometheus [RelabelConfigs] to apply to samples before scraping
      relabelings: []
      # -- Prometheus [MetricRelabelConfigs] to apply to samples before ingestion
      metricRelabelings: []
      # -- Prometheus ServiceMonitor selector
      selector: {{}}
        # prometheus: kube-prometheus

      # -- Prometheus ServiceMonitor scheme
      scheme: ""
      # -- Prometheus ServiceMonitor tlsConfig
      tlsConfig: {{}}
      # -- Prometheus ServiceMonitor namespace
      namespace: "" # "monitoring"
      # -- Prometheus ServiceMonitor labels
      additionalLabels: {{}}
      # -- Prometheus ServiceMonitor annotations
      annotations: {{}}


## Server
server:
  # -- Argo CD server name
  name: server

  # -- The number of server pods to run
  replicas: 1

  # -- Resource limits and requests for the Argo CD server
  resources: {{}}
  #  limits:
  #    cpu: 100m
  #    memory: 128Mi
  #  requests:
  #    cpu: 50m
  #    memory: 64Mi



  ## Server metrics service configuration
  metrics:
    # -- Deploy metrics service
    enabled: true
    service:
      # -- Metrics service type
      type: ClusterIP
      # -- Metrics service clusterIP. `None` makes a "headless service" (no virtual IP)
      clusterIP: ""
      # -- Metrics service annotations
      annotations: {{}}
      # -- Metrics service labels
      labels: {{}}
      # -- Metrics service port
      servicePort: 8083
      # -- Metrics service port name
      portName: http-metrics
    serviceMonitor:
      # -- Enable a prometheus ServiceMonitor
      enabled: true
      # -- Prometheus ServiceMonitor interval
      interval: 30s
      # -- Prometheus ServiceMonitor scrapeTimeout. If empty, Prometheus uses the global scrape timeout unless it is less than the target's scrape interval value in which the latter is used.
      scrapeTimeout: ""
      # -- When true, honorLabels preserves the metric’s labels when they collide with the target’s labels.
      honorLabels: false
      # -- Prometheus [RelabelConfigs] to apply to samples before scraping
      relabelings: []
      # -- Prometheus [MetricRelabelConfigs] to apply to samples before ingestion
      metricRelabelings: []
      # -- Prometheus ServiceMonitor selector
      selector: {{}}
        # prometheus: kube-prometheus

      # -- Prometheus ServiceMonitor scheme
      scheme: ""
      # -- Prometheus ServiceMonitor tlsConfig
      tlsConfig: {{}}
      # -- Prometheus ServiceMonitor namespace
      namespace: ""  # monitoring
      # -- Prometheus ServiceMonitor labels
      additionalLabels: {{}}
      # -- Prometheus ServiceMonitor annotations
      annotations: {{}}

  # Argo CD server ingress configuration
  ingress:
    # -- Enable an ingress resource for the Argo CD server
    enabled: true
    # -- Specific implementation for ingress controller. One of `generic`, `aws` or `gke`
    ## Additional configuration might be required in related configuration sections
    controller: generic
    # -- Additional ingress labels
    labels: {{}}
    # -- Additional ingress annotations
    ## Ref: https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/#option-1-ssl-passthrough
    annotations: {{}}
      # nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
      # nginx.ingress.kubernetes.io/ssl-passthrough: "true"

    # -- Defines which ingress controller will implement the resource
    ingressClassName: ""

    # -- Argo CD server hostname
    # @default -- `""` (defaults to global.domain)
    hostname: ""

    # -- The path to Argo CD server
    path: /

    # -- Ingress path type. One of `Exact`, `Prefix` or `ImplementationSpecific`
    pathType: Prefix

    # -- Enable TLS configuration for the hostname defined at `server.ingress.hostname`
    ## TLS certificate will be retrieved from a TLS secret `argocd-server-tls`
    ## You can create this secret via `certificate` or `certificateSecret` option
    tls: false

    # -- The list of additional hostnames to be covered by ingress record
    # @default -- `[]` (See [values.yaml])
    extraHosts: []
      # - name: argocd.example.com
      #   path: /

    # -- Additional ingress paths
    # @default -- `[]` (See [values.yaml])
    ## Note: Supports use of custom Helm templates
    extraPaths: []
      # - path: /*
      #   pathType: Prefix
      #   backend:
      #     service:
      #       name: ssl-redirect
      #       port:
      #         name: use-annotation

    # -- Additional ingress rules
    # @default -- `[]` (See [values.yaml])
    ## Note: Supports use of custom Helm templates
    extraRules: []
      # - http:
      #     paths:
      #     - path: /
      #       pathType: Prefix
      #       backend:
      #         service:
      #           name: '{{{{ include "argo-cd.server.fullname" . }}}}'
      #           port:
      #             name: '{{{{ .Values.server.service.servicePortHttpsName }}}}'

    # -- Additional TLS configuration
    # @default -- `[]` (See [values.yaml])
    extraTls: []
      # - hosts:
      #   - argocd.example.com
      #   secretName: your-certificate-name


  # Create a OpenShift Route with SSL passthrough for UI and CLI
  # Consider setting 'hostname' e.g. https://argocd.apps-crc.testing/ using your Default Ingress Controller Domain
  # Find your domain with: kubectl describe --namespace=openshift-ingress-operator ingresscontroller/default | grep Domain:
  # If 'hostname' is an empty string "" OpenShift will create a hostname for you.
  route:
    # -- Enable an OpenShift Route for the Argo CD server
    enabled: {openshift}
    # -- Openshift Route annotations
    annotations: {{}}
    # -- Hostname of OpenShift Route
    hostname: ""
    # -- Termination type of Openshift Route
    termination_type: passthrough
    # -- Termination policy of Openshift Route
    termination_policy: None

## Repo Server
repoServer:
  # -- Repo server name
  name: repo-server

  # -- The number of repo server pods to run
  replicas: 1

  # -- Resource limits and requests for the repo server pods
  resources: {{}}
  #  limits:
  #    cpu: 50m
  #    memory: 128Mi
  #  requests:
  #    cpu: 10m
  #    memory: 64Mi

  ## Repo server metrics service configuration
  metrics:
    # -- Deploy metrics service
    enabled: true
    service:
      # -- Metrics service type
      type: ClusterIP
      # -- Metrics service clusterIP. `None` makes a "headless service" (no virtual IP)
      clusterIP: ""
      # -- Metrics service annotations
      annotations: {{}}
      # -- Metrics service labels
      labels: {{}}
      # -- Metrics service port
      servicePort: 8084
      # -- Metrics service port name
      portName: http-metrics
    serviceMonitor:
      # -- Enable a prometheus ServiceMonitor
      enabled: true
      # -- Prometheus ServiceMonitor interval
      interval: 30s
      # -- Prometheus ServiceMonitor scrapeTimeout. If empty, Prometheus uses the global scrape timeout unless it is less than the target's scrape interval value in which the latter is used.
      scrapeTimeout: ""
      # -- When true, honorLabels preserves the metric’s labels when they collide with the target’s labels.
      honorLabels: false
      # -- Prometheus [RelabelConfigs] to apply to samples before scraping
      relabelings: []
      # -- Prometheus [MetricRelabelConfigs] to apply to samples before ingestion
      metricRelabelings: []
      # -- Prometheus ServiceMonitor selector
      selector: {{}}
        # prometheus: kube-prometheus

      # -- Prometheus ServiceMonitor scheme
      scheme: ""
      # -- Prometheus ServiceMonitor tlsConfig
      tlsConfig: {{}}
      # -- Prometheus ServiceMonitor namespace
      namespace: "" # "monitoring"
      # -- Prometheus ServiceMonitor labels
      additionalLabels: {{}}
      # -- Prometheus ServiceMonitor annotations
      annotations: {{}}


## ApplicationSet controller
applicationSet:
  # -- ApplicationSet controller name string
  name: applicationset-controller

  # -- The number of ApplicationSet controller pods to run
  replicas: 1


  ## Metrics service configuration
  metrics:
    # -- Deploy metrics service
    enabled: true
    service:
      # -- Metrics service type
      type: ClusterIP
      # -- Metrics service clusterIP. `None` makes a "headless service" (no virtual IP)
      clusterIP: ""
      # -- Metrics service annotations
      annotations: {{}}
      # -- Metrics service labels
      labels: {{}}
      # -- Metrics service port
      servicePort: 8080
      # -- Metrics service port name
      portName: http-metrics
    serviceMonitor:
      # -- Enable a prometheus ServiceMonitor
      enabled: true
      # -- Prometheus ServiceMonitor interval
      interval: 30s
      # -- Prometheus ServiceMonitor scrapeTimeout. If empty, Prometheus uses the global scrape timeout unless it is less than the target's scrape interval value in which the latter is used.
      scrapeTimeout: ""
      # -- When true, honorLabels preserves the metric’s labels when they collide with the target’s labels.
      honorLabels: false
      # -- Prometheus [RelabelConfigs] to apply to samples before scraping
      relabelings: []
      # -- Prometheus [MetricRelabelConfigs] to apply to samples before ingestion
      metricRelabelings: []
      # -- Prometheus ServiceMonitor selector
      selector: {{}}
        # prometheus: kube-prometheus

      # -- Prometheus ServiceMonitor scheme
      scheme: ""
      # -- Prometheus ServiceMonitor tlsConfig
      tlsConfig: {{}}
      # -- Prometheus ServiceMonitor namespace
      namespace: ""  # monitoring
      # -- Prometheus ServiceMonitor labels
      additionalLabels: {{}}
      # -- Prometheus ServiceMonitor annotations
      annotations: {{}}

  # -- Resource limits and requests for the ApplicationSet controller pods.
  resources: {{}}
    # limits:
    #   cpu: 100m
    #   memory: 128Mi
    # requests:
    #   cpu: 100m
    #   memory: 128Mi


  # -- Enable ApplicationSet in any namespace feature
  allowAnyNamespace: false
## Notifications controller
notifications:
  # -- Enable notifications controller
  enabled: true

  # -- Notifications controller name string
  name: notifications-controller

  # -- Argo CD dashboard url; used in place of {{{{.context.argocdUrl}}}} in templates
  # @default -- `""` (defaults to https://`global.domain`)
  argocdUrl: ""


  secret:
    # -- Whether helm chart creates notifications controller secret
    ## If true, will create a secret with the name below. Otherwise, will assume existence of a secret with that name.
    create: true

    # -- notifications controller Secret name
    name: "argocd-notifications-secret"
    # -- Generic key:value pairs to be inserted into the secret
    ## Can be used for templates, notification services etc. Some examples given below.
    ## For more information: https://argo-cd.readthedocs.io/en/stable/operator-manual/notifications/services/overview/
    items: {{}}
      # slack-token:
      #   # For more information: https://argo-cd.readthedocs.io/en/stable/operator-manual/notifications/services/slack/

      # grafana-apiKey:
      #   # For more information: https://argo-cd.readthedocs.io/en/stable/operator-manual/notifications/services/grafana/

      # webhooks-github-token:

      # email-username:
      # email-password:
        # For more information: https://argo-cd.readthedocs.io/en/stable/operator-manual/notifications/services/email/

  metrics:
    # -- Enables prometheus metrics server
    enabled: true
    # -- Metrics port
    port: 9001
    service:
      # -- Metrics service type
      type: ClusterIP
      # -- Metrics service clusterIP. `None` makes a "headless service" (no virtual IP)
      clusterIP: ""
      # -- Metrics service annotations
      annotations: {{}}
      # -- Metrics service labels
      labels: {{}}
      # -- Metrics service port name
      portName: http-metrics
    serviceMonitor:
      # -- Enable a prometheus ServiceMonitor
      enabled: true
      # -- Prometheus ServiceMonitor selector
      selector: {{}}
        # prometheus: kube-prometheus
      # -- Prometheus ServiceMonitor labels
      additionalLabels: {{}}
      # -- Prometheus ServiceMonitor annotations
      annotations: {{}}
      # namespace: monitoring
      # interval: 30s
      # scrapeTimeout: 10s
      # -- Prometheus ServiceMonitor scheme
      scheme: ""
      # -- Prometheus ServiceMonitor tlsConfig
      tlsConfig: {{}}
      # -- When true, honorLabels preserves the metric’s labels when they collide with the target’s labels.
      honorLabels: false
      # -- Prometheus [RelabelConfigs] to apply to samples before scraping
      relabelings: []
      # -- Prometheus [MetricRelabelConfigs] to apply to samples before ingestion
      metricRelabelings: []

  # -- Configures notification services such as slack, email or custom webhook
  # @default -- See [values.yaml]
  ## For more information: https://argo-cd.readthedocs.io/en/stable/operator-manual/notifications/services/overview/
  notifiers: {{}}
    # service.slack: |
    #   token: $slack-token

  # -- Resource limits and requests for the notifications controller
  resources: {{}}
    # limits:
    #   cpu: 100m
    #   memory: 128Mi
    # requests:
    #   cpu: 100m
    #   memory: 128Mi

  cm:
    # -- Whether helm chart creates notifications controller config map
    create: true


  # -- Contains centrally managed global application subscriptions
  ## For more information: https://argo-cd.readthedocs.io/en/stable/operator-manual/notifications/subscriptions/
  subscriptions: []
    # # subscription for on-sync-status-unknown trigger notifications
    # - recipients:
    #   - slack:test2
    #   - email:test@gmail.com
    #   triggers:
    #   - on-sync-status-unknown
    # # subscription restricted to applications with matching labels only
    # - recipients:
    #   - slack:test3
    #   selector: test=true
    #   triggers:
    #   - on-sync-status-unknown

  # -- The notification template is used to generate the notification content
  ## For more information: https://argo-cd.readthedocs.io/en/stable/operator-manual/notifications/templates/
  templates: {{}}

commitServer:
  # -- Enable commit server
  enabled: false

"#,
    );

    HelmChartScore {
        namespace: Some(NonBlankString::from_str(&namespace).unwrap()),
        release_name: NonBlankString::from_str("argo-cd").unwrap(),
        chart_name: NonBlankString::from_str("argo/argo-cd").unwrap(),
        chart_version: Some(NonBlankString::from_str("8.1.2").unwrap()),
        values_overrides: None,
        values_yaml: Some(values.to_string()),
        create_namespace: true,
        install_only: false,
        repository: Some(HelmRepository::new(
            "argo".to_string(),
            url::Url::parse("https://argoproj.github.io/argo-helm").unwrap(),
            true,
        )),
    }
}
