# Copyright (C) 2022 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 os.path

from copy import deepcopy
from pathlib import Path

import pytest
import yaml

import pygit2 as git
from kubernetes import client

from .abstract_deployment import AbstractDeployment


class TimeOutException(Exception):
    """Exception to be raised, if some action does not finish in time."""


def dict_to_git_config(config_dict):
    config = ""
    for section, options in config_dict.items():
        config += f"[{section}]\n"
        for key, value in options.items():
            if isinstance(value, bool):
                value = "true" if value else "false"
            elif isinstance(value, list):
                for opt in value:
                    config += f"  {key} = {opt}\n"
                continue
            config += f"  {key} = {value}\n"
    return config


GERRIT_STARTUP_TIMEOUT = 240

DEFAULT_GERRIT_CONFIG = {
    "auth": {"type": "DEVELOPMENT_BECOME_ANY_ACCOUNT"},
    "container": {
        "user": "gerrit",
        "javaHome": "/usr/lib/jvm/java-11-openjdk",
        "javaOptions": [
            "-Djavax.net.ssl.trustStore=/var/gerrit/etc/keystore",
            "-Xms200m",
            "-Xmx4g",
        ],
    },
    "gerrit": {
        "basePath": "git",
        "canonicalWebUrl": "http://example.com/",
        "serverId": "gerrit-1",
    },
    "httpd": {
        "listenUrl": "proxy-https://*:8080/",
        "requestLog": True,
        "gracefulStopTimeout": "1m",
    },
    "index": {"type": "LUCENE", "onlineUpgrade": False},
    "sshd": {"listenAddress": "off"},
}

DEFAULT_VALUES = {
    "gitRepositoryStorage": {"externalPVC": {"use": True, "name": "repo-storage"}},
    "gitGC": {"logging": {"persistence": {"enabled": False}}},
    "gerrit": {
        "etc": {"config": {"gerrit.config": dict_to_git_config(DEFAULT_GERRIT_CONFIG)}}
    },
}


class GerritDeployment(AbstractDeployment):
    def __init__(
        self,
        tmp_dir,
        cluster,
        storageclass,
        container_registry,
        container_org,
        container_version,
        ingress_url,
    ):
        super().__init__(tmp_dir)
        self.cluster = cluster
        self.storageclass = storageclass

        self.chart_name = "gerrit-" + self.namespace
        self.chart_path = os.path.join(
            # pylint: disable=E1101
            Path(git.discover_repository(os.path.realpath(__file__))).parent.absolute(),
            "helm-charts",
            "gerrit",
        )

        self.gerrit_config = deepcopy(DEFAULT_GERRIT_CONFIG)
        self.chart_opts = deepcopy(DEFAULT_VALUES)

        self._configure_container_images(
            container_registry, container_org, container_version
        )
        self.hostname = f"{self.namespace}.{ingress_url}"
        self._configure_ingress()

    def install(self, wait=True):
        if self.cluster.helm.is_installed(self.namespace, self.chart_name):
            self.update()
            return

        with open(self.values_file, "w", encoding="UTF-8") as f:
            yaml.dump(self.chart_opts, f)

        self.cluster.create_namespace(self.namespace)
        self._create_pvc()

        self.cluster.helm.install(
            self.chart_path,
            self.chart_name,
            values_file=self.values_file,
            fail_on_err=True,
            namespace=self.namespace,
            wait=wait,
        )

    def update(self):
        with open(self.values_file, "w", encoding="UTF-8") as f:
            yaml.dump(self.chart_opts, f)

        self.cluster.helm.upgrade(
            self.chart_path,
            self.chart_name,
            values_file=self.values_file,
            fail_on_err=True,
            namespace=self.namespace,
        )

    def wait_until_ready(self):
        pod_labels = f"app=gerrit,release={self.chart_name}"
        finished_in_time = self._wait_for_pod_readiness(
            pod_labels, timeout=GERRIT_STARTUP_TIMEOUT
        )

        if not finished_in_time:
            raise TimeOutException(
                f"Gerrit pod was not ready in time ({GERRIT_STARTUP_TIMEOUT} s)."
            )

    def uninstall(self):
        self.cluster.helm.delete(self.chart_name, namespace=self.namespace)
        self.cluster.delete_namespace(self.namespace)

    def set_gerrit_config_value(self, section, key, value):
        if isinstance(self.gerrit_config[section][key], list):
            self.gerrit_config[section][key].append(value)
        else:
            self.gerrit_config[section][key] = value
        # pylint: disable=W1401
        self.set_helm_value(
            "gerrit.etc.config.gerrit\.config", dict_to_git_config(self.gerrit_config)
        )

    def _set_values_file(self):
        return os.path.join(self.tmp_dir, "values.yaml")

    def _configure_container_images(
        self, container_registry, container_org, container_version
    ):
        self.set_helm_value("images.registry.name", container_registry)
        self.set_helm_value("gitGC.image", f"{container_org}/git-gc")
        self.set_helm_value("gerrit.images.gerritInit", f"{container_org}/gerrit-init")
        self.set_helm_value("gerrit.images.gerrit", f"{container_org}/gerrit")
        self.set_helm_value("images.version", container_version)

    def _configure_ingress(self):
        self.set_helm_value("ingress.enabled", True)
        self.set_helm_value("ingress.host", self.hostname)

    def _create_pvc(self):
        core_v1 = client.CoreV1Api()
        core_v1.create_namespaced_persistent_volume_claim(
            self.namespace,
            body=client.V1PersistentVolumeClaim(
                kind="PersistentVolumeClaim",
                api_version="v1",
                metadata=client.V1ObjectMeta(name="repo-storage"),
                spec=client.V1PersistentVolumeClaimSpec(
                    access_modes=["ReadWriteMany"],
                    storage_class_name=self.storageclass,
                    resources=client.V1ResourceRequirements(
                        requests={"storage": "1Gi"}
                    ),
                ),
            ),
        )


@pytest.fixture(scope="class")
def gerrit_deployment(request, tmp_path_factory, test_cluster):
    deployment = GerritDeployment(
        tmp_path_factory.mktemp("gerrit_deployment"),
        test_cluster,
        request.config.getoption("--rwm-storageclass").lower(),
        request.config.getoption("--registry"),
        request.config.getoption("--org"),
        request.config.getoption("--tag"),
        request.config.getoption("--ingress-url"),
    )

    yield deployment

    deployment.uninstall()


@pytest.fixture(scope="class")
def default_gerrit_deployment(gerrit_deployment):
    gerrit_deployment.install()

    yield gerrit_deployment
