# 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.path
import re
import time

import pytest

MYSQL_CONFIG = {
    "MYSQL_HOST": "k8sgerrit-mysql",
    "MYSQL_PORT": 3306,
    "MYSQL_ROOT_PASSWORD": "big_secret",
    "REPL_PASSWORD": "test",
}


@pytest.fixture()
def mock_dump():
    return (
        "CREATE DATABASE `users`;"
        "USE `users`;"
        "CREATE TABLE `users` ("
        "`id` INT(11) NOT NULL,"
        "`first_name` VARCHAR(50),"
        "`last_name` VARCHAR(50),"
        "`password` VARCHAR(100),"
        "PRIMARY KEY (`id`))"
    )


@pytest.fixture(scope="module")
def mock_sql_script(tmp_path_factory):
    tmp_dir = tmp_path_factory.mktemp("mysql_init_script")
    with open(os.path.join(tmp_dir, "initialize-slave.sql"), "w") as sql_file:
        sql_file.write(
            (
                "USE `users`;"
                "SET @query = CONCAT("
                '"INSERT INTO `users` (id, first_name, last_name, password) ",'
                "\"VALUES (1, 'John', 'Doe', '\", @replpwd, \"');\");"
                "PREPARE stmt FROM @query;"
                "EXECUTE stmt;"
            )
        )
    return tmp_dir


@pytest.fixture(scope="module")
def mysql_container(request, docker_client, docker_network, mysql_container_factory):
    mysql_container = mysql_container_factory(
        docker_client, docker_network, MYSQL_CONFIG
    )
    mysql_container.start()

    request.addfinalizer(mysql_container.stop)

    return mysql_container


@pytest.fixture(scope="module")
def init_container(
    request,
    docker_client,
    docker_network,
    mysql_replication_init_image,
    mock_sql_script,
):
    container_run = docker_client.containers.run(
        image=mysql_replication_init_image.id,
        environment=MYSQL_CONFIG,
        volumes={mock_sql_script: {"bind": "/var/sql", "mode": "ro"}},
        network=docker_network.name,
        name="mysql-replication-init",
        detach=True,
    )

    def stop_container():
        container_run.stop(timeout=1)
        container_run.remove(v=True, force=True)

    request.addfinalizer(stop_container)

    return container_run


@pytest.fixture(scope="module")
def containers(mysql_container, init_container):
    return mysql_container, init_container


@pytest.mark.slow
@pytest.mark.incremental
class TestMysqlInitScript:
    def test_mysql_replication_init_waiting_for_dump(self, containers):
        (_, init_container) = containers
        timeout = time.time() + 20
        while time.time() < timeout:
            last_log_line = init_container.logs(tail=1).decode("utf-8").strip()
            if (
                last_log_line
                == "Waiting for database dump file at /var/data/db/master_dump.sql"
            ):
                break
        assert timeout > time.time()

    def test_mysql_replication_init_accepts_dump(self, containers, mock_dump):
        (_, init_container) = containers
        cmd = "/bin/bash -c \"echo '%s' > /var/data/db/master_dump.sql\"" % mock_dump
        init_container.exec_run(cmd)
        timeout = time.time() + 20
        while time.time() < timeout:
            logs = init_container.logs().decode("utf-8")
            if re.search(r"Database dump received", logs):
                break
        assert timeout > time.time()

    def test_mysql_replication_init_finishes(self, containers):
        (_, init_container) = containers
        timeout = time.time() + 20
        while time.time() < timeout:
            init_container.reload()
            if init_container.status == "exited":
                break
        assert timeout > time.time()
        assert init_container.attrs["State"]["ExitCode"] == 0

    def test_mysql_replication_init_applies_dump(self, containers):
        (mysql_container, _) = containers
        connection = mysql_container.connect()
        result = connection.execute("SHOW DATABASES;")
        connection.close()
        assert "users" in [row[0] for row in result]

    def test_mysql_replication_init_runs_slave_init_script(self, containers):
        (mysql_container, _) = containers
        connection = mysql_container.connect()
        result = connection.execute("USE `users`;")
        result = connection.execute("SELECT password FROM users WHERE id=1 LIMIT 1;")
        connection.close()
        for row in result:
            assert MYSQL_CONFIG["REPL_PASSWORD"] in row["password"]
