#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.

"""
Safe docker run tests
"""
import itertools
import os
import signal
import unittest
from typing import Optional
from unittest.mock import create_autospec, patch, call

from docker import DockerClient
from docker.models.containers import Container, ContainerCollection

from safe_docker_run import SafeDockerClient, main


def create_mock_container(status_code: int = 0):
    """
    Creates a mock docker container that exits with the specified status code
    """
    mock_container = create_autospec(Container, name="mock_container")
    mock_container.wait.return_value = {
        "StatusCode": status_code
    }
    return mock_container


def create_mock_container_collection(container: Container):
    """
    Creates a mock ContainerCollection that return the supplied container when the 'run' method is called
    """
    mock_container_collection = create_autospec(ContainerCollection, name="mock_collection")
    mock_container_collection.run.return_value = container
    return mock_container_collection


class MockDockerClient:
    """
    A mock DockerClient when docker.from_env is called
    The supplied container will be returned when the client.containers.run method is called
    """
    def __init__(self, container: Container):
        self._mock_client = create_autospec(DockerClient, name="mock_client")
        self._mock_client.containers = create_mock_container_collection(container)
        self._patch = patch("docker.from_env", return_value=self._mock_client)

    def __enter__(self):
        self._patch.start()
        return self._mock_client

    def __exit__(self, _, __, ___):
        self._patch.stop()


class TestSafeDockerRun(unittest.TestCase):

    @patch("safe_docker_run.signal.pthread_sigmask")
    @patch.dict(os.environ, {
        "BUILD_NUMBER": "BUILD_NUMBER_5",
        "BUILD_ID": "BUILD_ID_1",
        "BUILD_TAG": "BUILD_TAG_7"
    })
    def test_run_successful(self, mock_pthread_sigmask):
        """
        Tests successful run
        """
        mock_container = create_mock_container()

        with MockDockerClient(mock_container) as mock_client:
            safe_docker = SafeDockerClient()

            # Check return code is 0
            assert safe_docker.run("image", "command") == 0

            # Check call to container is correct
            assert mock_client.containers.run.call_args_list == [
                call("image", "command", detach=True, environment={
                    "BUILD_NUMBER": "BUILD_NUMBER_5",
                    "BUILD_ID": "BUILD_ID_1",
                    "BUILD_TAG": "BUILD_TAG_7"
                })
            ]

            # Check correct signals are blocked then unblocked
            assert mock_pthread_sigmask.call_args_list == [
                call(signal.SIG_BLOCK, {signal.SIGINT, signal.SIGTERM}),
                call(signal.SIG_UNBLOCK, {signal.SIGINT, signal.SIGTERM})
            ]

            # Assert container is stopped and removed
            assert mock_container.stop.call_count == 1
            assert mock_container.remove.call_count == 1
            assert len(safe_docker._containers) == 0

    def test_run_detach(self):
        """
        Tests detach=True is passed to the underlying call by default
        """
        mock_container = create_mock_container()

        # Test detach=True is passed in even if not specified
        with MockDockerClient(mock_container) as mock_client:
            safe_docker = SafeDockerClient()
            assert safe_docker.run("image", "command") == 0
            assert mock_client.containers.run.call_count == 1
            _, kwargs = mock_client.containers.run.call_args
            assert kwargs["detach"] is True

        # Test passing in detach=True does not cause any issues
        with MockDockerClient(mock_container) as mock_client:
            safe_docker = SafeDockerClient()
            assert safe_docker.run("image", "command", detach=True) == 0
            assert mock_client.containers.run.call_count == 1
            _, kwargs = mock_client.containers.run.call_args
            assert kwargs["detach"] is True

        # Test detach=False fails
        with MockDockerClient(mock_container) as mock_client:
            safe_docker = SafeDockerClient()
            with self.assertRaises(ValueError):
                safe_docker.run("image", "command", detach=False)
                assert mock_client.containers.run.call_args_list == []

    def test_jenkins_vars(self):
        """
        Tests jenkins environment variables are appropriately passed to the underlying docker run call
        """
        # NOTE: It's important that these variables are passed to the underlying docker container
        # These variables are passed to the container so the process tree killer can find runaway
        # process inside the container
        # https://wiki.jenkins.io/display/JENKINS/ProcessTreeKiller
        # https://github.com/jenkinsci/jenkins/blob/578d6bacb33a5e99f149de504c80275796f0b231/core/src/main/java/hudson/model/Run.java#L2393

        jenkins_vars = {
            "BUILD_NUMBER": "BUILD_NUMBER_5",
            "BUILD_ID": "BUILD_ID_1",
            "BUILD_TAG": "BUILD_TAG_7"
        }
        mock_container = create_mock_container()

        # Test environment is empty if the jenkins vars are not present
        with MockDockerClient(mock_container) as mock_client:
            safe_docker = SafeDockerClient()
            assert safe_docker.run("image", "command") == 0
            assert mock_client.containers.run.call_count == 1
            _, kwargs = mock_client.containers.run.call_args
            assert kwargs["environment"] == {}

        # Test environment contains jenkins env vars if they are present
        with MockDockerClient(mock_container) as mock_client:
            with patch.dict(os.environ, jenkins_vars):
                safe_docker = SafeDockerClient()
                assert safe_docker.run("image", "command") == 0
                assert mock_client.containers.run.call_count == 1
                _, kwargs = mock_client.containers.run.call_args
                assert kwargs["environment"] == jenkins_vars

        # Test jenkins env vars are added to callers env vars
        user_env = {"key1": "value1", "key2": "value2"}
        with MockDockerClient(mock_container) as mock_client:
            with patch.dict(os.environ, jenkins_vars):
                safe_docker = SafeDockerClient()
                assert safe_docker.run("image", "command", environment=user_env) == 0
                assert mock_client.containers.run.call_count == 1
                _, kwargs = mock_client.containers.run.call_args
                assert kwargs["environment"] == {**jenkins_vars, **user_env}

    def test_run_args_kwargs_passed(self):
        """
        Tests args and kwargs are passed to the container run call
        """
        mock_container = create_mock_container()

        # Test detach=True is passed in even if not specified
        with MockDockerClient(mock_container) as mock_client:
            safe_docker = SafeDockerClient()
            assert safe_docker.run(
                "image",
                "command",
                "another_arg",
                str_param="value",
                bool_param=True,
                none_param=None,
                int_param=5,
                float_param=5.2,
                list_param=["this", "is", "a", "list"],
                map_param={
                    "a": "5",
                    "b": True,
                    "c": 2
                }) == 0
            assert mock_client.containers.run.call_args_list == [
                call(
                    "image",
                    "command",
                    "another_arg",
                    detach=True,
                    environment={},
                    str_param="value",
                    bool_param=True,
                    none_param=None,
                    int_param=5,
                    float_param=5.2,
                    list_param=["this", "is", "a", "list"],
                    map_param={
                        "a": "5",
                        "b": True,
                        "c": 2
                    }
                )
            ]

    def test_container_returns_non_zero_status_code(self):
        """
        Tests non-zero code from container is returned and the container
        is cleaned up
        """
        mock_container = create_mock_container(status_code=10)
        with MockDockerClient(mock_container):
            safe_docker = SafeDockerClient()
            # check return code and that container gets cleaned up
            assert safe_docker.run("image", "command") == 10
            assert mock_container.stop.call_count == 1
            assert mock_container.remove.call_count == 1
            assert len(safe_docker._containers) == 0

    def test_container_wait_raises_returns_150(self):
        """
        Tests 150 is returned if an error is raised when calling container.wait
        """
        mock_container = create_mock_container()
        mock_container.wait.side_effect = RuntimeError("Something bad happened")
        with MockDockerClient(mock_container):
            safe_docker = SafeDockerClient()
            assert safe_docker.run("image", "command") == 150

    def test_container_stop_raises_returns_151(self):
        """
        Tests 151 is returned if an error is raised when calling container.stop
        """
        mock_container = create_mock_container()
        mock_container.stop.side_effect = RuntimeError("Something bad happened")
        with MockDockerClient(mock_container):
            safe_docker = SafeDockerClient()
            assert safe_docker.run("image", "command") == 151

    def test_container_remove_raises_returns_152(self):
        """
        Tests 152 is returned if an error is raised when calling container.remove
        """
        mock_container = create_mock_container()
        mock_container.remove.side_effect = RuntimeError("Something bad happened")
        with MockDockerClient(mock_container):
            safe_docker = SafeDockerClient()
            assert safe_docker.run("image", "command") == 152

    def test_main(self):
        """
        Tests main function against different command line arguments
        """
        tests = [
            # ( supplied command line arguments, expected call )
            (
                ["image", "command"],
                call("image", command="command", runtime=None, user=None, name=None, volumes={}, cap_add=[])
            ),
            (
                ["image", "command", "arg1", "arg2"],
                call("image", command="command arg1 arg2", runtime=None, user=None, name=None, volumes={}, cap_add=[])
            ),
            (
                ["--runtime", "nvidia", "image", "command"],
                call("image", command="command", runtime="nvidia", user=None, name=None, volumes={}, cap_add=[])
            ),
            (
                ["--user", "1001:1001", "image", "command"],
                call("image", command="command", runtime=None, user="1001:1001", name=None, volumes={}, cap_add=[])
            ),
            ([
                "--volume", "/local/path1:/container/path1",
                "--volume", "/local/path2:/container/path2:ro",
                "image",
                "command"
            ], call("image", command="command", runtime=None, user=None, name=None, volumes={
                "/local/path1": {
                    "bind": "/container/path1",
                    "mode": "rw"
                },
                "/local/path2": {
                    "bind": "/container/path2",
                    "mode": "ro"
                }
            }, cap_add=[])),
            ([
                "--runtime", "nvidia",
                "-u", "1001:1001",
                "-v", "/local/path1:/container/path1",
                "-v", "/local/path2:/container/path2:ro",
                "--cap-add", "bob",
                "--cap-add", "jimmy",
                "--name",
                "container_name",
                "image",
                "command",
                "arg1",
                "arg2"
            ], call(
                "image",
                command="command arg1 arg2",
                runtime="nvidia",
                user="1001:1001",
                name="container_name",
                volumes={
                    "/local/path1": {
                        "bind": "/container/path1",
                        "mode": "rw"
                    },
                    "/local/path2": {
                        "bind": "/container/path2",
                        "mode": "ro"
                    }
                }, cap_add=["bob", "jimmy"])
            )
        ]

        # Tests valid arguments
        mock_docker = create_autospec(SafeDockerClient)
        mock_docker.run.return_value = 0
        with patch("safe_docker_run.SafeDockerClient", return_value=mock_docker):
            for test in tests:
                arguments, expected_call = test
                main(arguments)
                assert mock_docker.run.call_args == expected_call

        # Tests invalid arguments
        tests = [
            [],
            None,
            ["image"],
            # Test some bad volume mounts
            ["-v", "bob", "image", "args"],
            ["-v", "/local/path", "image", "args"],
            ["-v", "/local/path:/container/path:blah", "image", "args"],
            ["-v", "", "image", "args"],
            ["-v", "a:b:c:d", "image", "args"]
        ]

        mock_docker = create_autospec(SafeDockerClient)
        with patch("safe_docker_run.SafeDockerClient", return_value=mock_docker):
            with self.assertRaises(SystemExit):
                for test in tests:
                    main(test)

    def test_clean_up(self):
        """
        Tests container clean up in case of SIGTERM and SIGINT
        """
        import subprocess
        import time
        import docker.errors

        docker_client = docker.from_env()
        container_name = "safedockertestcontainer1234"

        def get_container(name: str) -> Optional[Container]:
            try:
                return docker_client.containers.get(name)
            except docker.errors.NotFound:
                return None

        def remove_container_if_exists(name: str):
            container = get_container(name)
            if container:
                container.stop()
                container.remove()

        def wait_for_container(name: str) -> bool:
            for _ in itertools.count(5):
                if get_container(name):
                    return True
                time.sleep(1)
            return False

        # Clear any containers with container name
        remove_container_if_exists(container_name)

        # None => not signal is emitted - we should still finish with no containers at the end due
        # to the atexit
        for sig in [None, signal.SIGTERM, signal.SIGINT]:
            # Execute the safe docker run script in a different process
            proc = subprocess.Popen(['python3','safe_docker_run.py', "--name", container_name, "ubuntu:18.04", "sleep 10"])
            # NOTE: we need to wait for the container to come up as not all operating systems support blocking signals
            if wait_for_container(container_name) is False:
                raise RuntimeError("Test container did not come up")

            # Issue the signal and wait for the process to finish
            if sig:
                proc.send_signal(sig)
            proc.wait()

            # The container should no longer exist
            assert get_container(container_name) is None
