# 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

import utils

@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/bash",
    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.incremental
class TestGerritInitEmptySite:
  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)

    finished_in_time, _ = utils.exec_fn_with_timeout(wait_for_init_success_message)
    assert finished_in_time

  def test_gerrit_init_exits_after_init(self, container_run_default):
    def wait_for_container_exit():
      try:
        container_run_default.reload()
        return None, False
      except NotFound:
        return None, True

    finished_in_time, _ = utils.exec_fn_with_timeout(wait_for_container_exit)
    assert finished_in_time
    assert container_run_default.attrs["State"]["ExitCode"] == 0

@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/bash -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/bash -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/bash -c '" + \
      "test -f /var/gerrit/plugins/download-commands.jar'"
    exit_code, _ = container_run_endless.exec_run(cmd)
    assert exit_code == 0

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