# 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 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", name, chart, "--dependency-update"]
        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, namespace=None):
        """Lists helm charts installed on the cluster.

        Keyword Arguments:
            namespace {str} -- Kubernetes namespace (default: {None})

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

        helm_cmd = ["list", "--all", "--output", "json"]
        if namespace:
            helm_cmd.extend(("--namespace", namespace))
        output = self._exec_command(helm_cmd).stdout
        return json.loads(output)

    def upgrade(
        self,
        chart,
        name,
        namespace,
        values_file=None,
        set_values=None,
        reuse_values=True,
        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
            namespace {str} -- Kubernetes namespace

        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})
            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, "--namespace", namespace, "--wait"]
        if values_file:
            helm_cmd.extend(("-f", values_file))
        if reuse_values:
            helm_cmd.append("--reuse-values")
        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, namespace=None):
        """Deletes a chart from the cluster

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

        Keyword Arguments:
            namespace {str} -- Kubernetes namespace (default: {None})

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

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

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

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

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