# Copyright (C) 2019 The Android Open Source Project
#
# 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.

import json
import subprocess


class Helm:
    def __init__(self, kubeconfig, kubecontext):
        """Wrapper for Helm CLI.

  Arguments:
    kubeconfig {str} -- Path to kubeconfig-file describing the cluster to
                        connect to.
    kubecontext {str} -- Name of the context to use.
  """

        self.kubeconfig = kubeconfig
        self.kubecontext = kubecontext

    def _exec_command(self, cmd, fail_on_err=True):
        base_cmd = [
            "helm",
            "--kubeconfig",
            self.kubeconfig,
            "--kube-context",
            self.kubecontext,
        ]
        return subprocess.run(
            base_cmd + cmd,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            check=fail_on_err,
            text=True,
        )

    def init(self, serviceaccount):
        """Installs tiller on the cluster.

    Arguments:
      serviceaccount {str} -- Name of the service account, which tiller is meant
                              to use.

    Returns:
      CompletedProcess -- CompletedProcess-object returned by subprocess
                          containing details about the result and output of the
                          executed command.
    """

        helm_cmd = ["init", "--wait", "--service-account", serviceaccount]
        return self._exec_command(helm_cmd)

    def install(
        self,
        chart,
        name,
        values_file=None,
        set_values=None,
        namespace=None,
        fail_on_err=True,
        wait=True,
    ):
        """Installs a chart on the cluster

      Arguments:
        chart {str} -- Release name or path of a helm chart
        name {str} -- Name with which the chart will be installed on the cluster

      Keyword Arguments:
        values_file {str} -- Path to a custom values.yaml file (default: {None})
        set_values {dict} -- Dictionary containing key-value-pairs that are used
                            to overwrite values in the values.yaml-file.
                            (default: {None})
        namespace {str} -- Namespace to install the release into (default: {default})
        fail_on_err {bool} -- Whether to fail with an exception if the installation
                              fails (default: {True})
        wait {bool} -- Whether to wait for all pods to be ready (default: {True})

      Returns:
        CompletedProcess -- CompletedProcess-object returned by subprocess
                            containing details about the result and output of the
                            executed command.
      """

        helm_cmd = ["install", chart, "--dep-up", "-n", name]
        if values_file:
            helm_cmd.extend(("-f", values_file))
        if set_values:
            opt_list = ["%s=%s" % (k, v) for k, v in set_values.items()]
            helm_cmd.extend(("--set", ",".join(opt_list)))
        if namespace:
            helm_cmd.extend(("--namespace", namespace))
        if wait:
            helm_cmd.append("--wait")
        return self._exec_command(helm_cmd, fail_on_err)

    def list(self):
        """Lists helm charts installed on the cluster.

    Returns:
      list -- List of helm chart realeases installed on the cluster.
    """

        helm_cmd = ["list", "--all", "--output", "json"]
        output = self._exec_command(helm_cmd).stdout
        output = json.loads(output)
        return output["Releases"]

    def upgrade(
        self,
        chart,
        name,
        values_file=None,
        set_values=None,
        reuse_values=True,
        recreate_pods=False,
        fail_on_err=True,
    ):
        """Updates a chart on the cluster

      Arguments:
        chart {str} -- Release name or path of a helm chart
        name {str} -- Name with which the chart will be installed on the cluster

      Keyword Arguments:
        values_file {str} -- Path to a custom values.yaml file (default: {None})
        set_values {dict} -- Dictionary containing key-value-pairs that are used
                            to overwrite values in the values.yaml-file.
                            (default: {None})
        reuse_values {bool} -- Whether to reuse existing not overwritten values
                              (default: {True})
        recreate_pods {bool} -- Whether to restart changed pods (default: {False})
        fail_on_err {bool} -- Whether to fail with an exception if the installation
                              fails (default: {True})

      Returns:
        CompletedProcess -- CompletedProcess-object returned by subprocess
                            containing details about the result and output of the
                            executed command.
      """
        helm_cmd = ["upgrade", name, chart, "--wait"]
        if values_file:
            helm_cmd.extend(("-f", values_file))
        if reuse_values:
            helm_cmd.append("--reuse-values")
        if recreate_pods:
            helm_cmd.append("--recreate-pods")
        if set_values:
            opt_list = ["%s=%s" % (k, v) for k, v in set_values.items()]
            helm_cmd.extend(("--set", ",".join(opt_list)))
        return self._exec_command(helm_cmd, fail_on_err)

    def delete(self, name, purge=True):
        """Deletes a chart from the cluster

      Arguments:
        name {str} -- Name of the chart to delete

      Keyword Arguments:
        purge {bool} -- Whether to also remove the release metadata as well
                        (default: {True})

      Returns:
        CompletedProcess -- CompletedProcess-object returned by subprocess
                            containing details about the result and output of the
                            executed command.
      """

        helm_cmd = ["delete", name]
        if purge:
            helm_cmd.append("--purge")
        return self._exec_command(helm_cmd)

    def delete_all(self, exceptions=None):
        """Deletes all charts on the cluster

    Keyword Arguments:
      exceptions {list} -- List of chart names not to delete (default: {None})
    """

        charts = self.list()
        for chart in charts:
            if chart["Name"] in exceptions:
                continue
            self.delete(chart["Name"])

    def reset(self):
        """Uninstall Tiller from cluster

    Returns:
      CompletedProcess -- CompletedProcess-object returned by subprocess
                          containing details about the result and output of the
                          executed command.
    """

        helm_cmd = ["reset", "--force"]
        return self._exec_command(helm_cmd, fail_on_err=True)
