# pylint: disable=E1101

# Copyright (C) 2018 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 re

from docker.errors import NotFound

import pytest


@pytest.fixture(scope="class")
def container_run_default(request, docker_client, gerrit_init_image, tmp_path_factory):
    tmp_site_dir = tmp_path_factory.mktemp("gerrit_site")
    container_run = docker_client.containers.run(
        image=gerrit_init_image.id,
        user="gerrit",
        volumes={tmp_site_dir: {"bind": "/var/gerrit", "mode": "rw"}},
        detach=True,
        auto_remove=True,
    )

    def stop_container():
        try:
            container_run.stop(timeout=1)
        except NotFound:
            print("Container already stopped.")

    request.addfinalizer(stop_container)

    return container_run


@pytest.fixture(scope="class")
def container_run_endless(docker_client, gerrit_init_image, tmp_path_factory):
    tmp_site_dir = tmp_path_factory.mktemp("gerrit_site")
    container_run = docker_client.containers.run(
        image=gerrit_init_image.id,
        entrypoint="/bin/ash",
        command=["-c", "tail -f /dev/null"],
        user="gerrit",
        volumes={tmp_site_dir: {"bind": "/var/gerrit", "mode": "rw"}},
        detach=True,
        auto_remove=True,
    )

    yield container_run
    container_run.stop(timeout=1)


@pytest.mark.docker
@pytest.mark.incremental
class TestGerritInitEmptySite:
    @pytest.mark.timeout(60)
    def test_gerrit_init_gerrit_is_initialized(self, container_run_default):
        def wait_for_init_success_message():
            log = container_run_default.logs().decode("utf-8")
            return log, re.search(r"Initialized /var/gerrit", log)

        while not wait_for_init_success_message():
            continue

    @pytest.mark.timeout(60)
    def test_gerrit_init_exits_after_init(self, container_run_default):
        def wait_for_container_exit():
            try:
                container_run_default.reload()
                return False
            except NotFound:
                return True

        while not wait_for_container_exit():
            continue

        assert container_run_default.attrs["State"]["ExitCode"] == 0


@pytest.mark.docker
@pytest.mark.incremental
class TestGerritInitPluginInstallation:
    def test_gerrit_init_plugins_are_installed(self, container_run_endless):
        exit_code, _ = container_run_endless.exec_run(
            "/var/tools/gerrit_init.py -s /var/gerrit -p replication -p reviewnotes"
        )
        assert exit_code == 0
        cmd = (
            "/bin/ash -c '"
            + "test -f /var/gerrit/plugins/replication.jar && "
            + "test -f /var/gerrit/plugins/reviewnotes.jar'"
        )
        exit_code, _ = container_run_endless.exec_run(cmd)
        assert exit_code == 0

    def test_gerrit_init_plugins_are_added_in_existing_site(
        self, container_run_endless
    ):
        exit_code, _ = container_run_endless.exec_run(
            "/var/tools/gerrit_init.py -s /var/gerrit -p replication -p reviewnotes -p hooks"
        )
        assert exit_code == 0

        cmd = (
            "/bin/ash -c '"
            + "test -f /var/gerrit/plugins/replication.jar && "
            + "test -f /var/gerrit/plugins/reviewnotes.jar && "
            + "test -f /var/gerrit/plugins/hooks.jar'"
        )
        exit_code, _ = container_run_endless.exec_run(cmd)
        assert exit_code == 0

    def test_gerrit_init_plugins_are_installed_in_existing_site(
        self, container_run_endless
    ):
        exit_code, _ = container_run_endless.exec_run(
            "/var/tools/gerrit_init.py -s /var/gerrit -p download-commands"
        )
        assert exit_code == 0

        cmd = "/bin/ash -c '" + "test -f /var/gerrit/plugins/download-commands.jar'"
        exit_code, _ = container_run_endless.exec_run(cmd)
        assert exit_code == 0

        cmd = "/bin/ash -c '" + "test -f /var/gerrit/plugins/reviewnotes.jar'"
        exit_code, _ = container_run_endless.exec_run(cmd)
        assert exit_code == 1
