# pylint: disable=W0613, 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 os
import os.path
import re

import pygit2 as git
import pytest
import requests

CONFIG_FILES = ["gerrit.config", "secure.config"]


@pytest.fixture(scope="module")
def tmp_dir(tmp_path_factory):
    return tmp_path_factory.mktemp("gerrit-replica-test")


@pytest.fixture(scope="class")
def container_run(
    request,
    docker_client,
    docker_network,
    tmp_dir,
    gerrit_image,
    gerrit_container_factory,
    free_port,
):
    configs = {
        "gerrit.config": """
      [gerrit]
        basePath = git

      [httpd]
        listenUrl = http://*:8080

      [container]
        replica = true

      [test]
        success = True
      """,
        "secure.config": """
      [test]
          success = True
      """,
    }

    test_setup = gerrit_container_factory(
        docker_client, docker_network, tmp_dir, gerrit_image, configs, free_port
    )
    test_setup.start()

    request.addfinalizer(test_setup.stop)

    return test_setup


@pytest.mark.docker
@pytest.mark.incremental
@pytest.mark.integration
@pytest.mark.slow
class TestGerritReplica:
    @pytest.fixture(params=CONFIG_FILES)
    def config_file_to_test(self, request):
        return request.param

    @pytest.fixture(params=["All-Users.git", "All-Projects.git"])
    def expected_repository(self, request):
        return request.param

    @pytest.mark.timeout(60)
    def test_gerrit_replica_gerrit_starts_up(self, container_run):
        def wait_for_gerrit_start():
            log = container_run.container.logs().decode("utf-8")
            return re.search(r"Gerrit Code Review .+ ready", log)

        while not wait_for_gerrit_start():
            continue

    def test_gerrit_replica_custom_gerrit_config_available(
        self, container_run, config_file_to_test
    ):
        exit_code, output = container_run.container.exec_run(
            f"git config --file=/var/gerrit/etc/{config_file_to_test} --get test.success"
        )
        output = output.decode("utf-8").strip()
        assert exit_code == 0
        assert output == "True"

    def test_gerrit_replica_repository_exists(self, container_run, expected_repository):
        exit_code, _ = container_run.container.exec_run(
            f"test -d /var/gerrit/git/{expected_repository}"
        )
        assert exit_code == 0

    def test_gerrit_replica_clone_repo_works(self, container_run, tmp_path_factory):
        container_run.container.exec_run("git init --bare /var/gerrit/git/test.git")
        clone_dest = tmp_path_factory.mktemp("gerrit_replica_clone_test")
        repo = git.clone_repository(
            f"http://localhost:{container_run.port}/test.git", clone_dest
        )
        assert repo.path == os.path.join(clone_dest, ".git/")

    def test_gerrit_replica_webui_not_accessible(self, container_run):
        response = requests.get(f"http://localhost:{container_run.port}")
        assert response.status_code == 404
        assert response.text == "Not Found"
