# Copyright (C) 2019 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.

"""Unittests for the hooks.py module."""

from io import StringIO
from pathlib import Path
import sys

import pytest

import hooks


@pytest.mark.parametrize(
    "data",
    (
        "",
        "#\n# foo\n",
        "# Bad shebang in script\n#!/foo\n",
    ),
)
def test_no_shebang(data: str) -> None:
    """Lines w/out shebangs should be rejected."""
    assert hooks.RepoHook._ExtractInterpFromShebang(data) is None


@pytest.mark.parametrize(
    "shebang, interp",
    (
        ("#!/foo", "/foo"),
        ("#! /foo", "/foo"),
        ("#!/bin/foo ", "/bin/foo"),
        ("#! /usr/foo ", "/usr/foo"),
        ("#! /usr/foo -args", "/usr/foo"),
    ),
)
def test_direct_interp(shebang: str, interp: str) -> None:
    """Lines whose shebang points directly to the interpreter."""
    assert hooks.RepoHook._ExtractInterpFromShebang(shebang) == interp


@pytest.mark.parametrize(
    "shebang, interp",
    (
        ("#!/usr/bin/env foo", "foo"),
        ("#!/bin/env foo", "foo"),
        ("#! /bin/env /bin/foo ", "/bin/foo"),
    ),
)
def test_env_interp(shebang: str, interp: str) -> None:
    """Lines whose shebang launches through `env`."""
    assert hooks.RepoHook._ExtractInterpFromShebang(shebang) == interp


def test_post_sync_argument_validation() -> None:
    """Test that post-sync hook requires exact API arguments."""

    class FakeProject:

        def __init__(self):
            self.worktree = "/some/path"
            self.enabled_repo_hooks = ["post-sync"]

    hook = hooks.RepoHook(
        hook_type="post-sync",
        hooks_project=FakeProject(),
        repo_topdir="/topdir",
        manifest_url="https://gerrit",
        allow_all_hooks=True,
    )

    old_stderr = sys.stderr
    sys.stderr = StringIO()

    try:
        # Call with missing arg `sync_duration_seconds`
        res = hook.Run(repo_topdir="/topdir")
        assert res is False
        assert "hook 'post-sync' called incorrectly" in sys.stderr.getvalue()

        # Mock _CheckHook and _ExecuteHook to test success path
        hook._CheckHook = lambda: None

        executed_kwargs = {}

        def fake_execute(**kw):
            executed_kwargs.update(kw)

        hook._ExecuteHook = fake_execute

        res = hook.Run(repo_topdir="/topdir", sync_duration_seconds=12.345)
        assert res is True
        assert executed_kwargs.get("sync_duration_seconds") == 12.345

    finally:
        sys.stderr = old_stderr


@pytest.mark.parametrize("yes_val", (True, False))
def test_repo_upload_yes_arg(tmp_path: Path, yes_val: bool) -> None:
    """Test that yes is passed in kwargs during hook execution."""

    class FakeProject:
        def __init__(self, worktree: str) -> None:
            self.worktree = worktree
            self.enabled_repo_hooks = ["pre-upload"]
            self.config = None

    hook_file = tmp_path / "pre-upload.py"

    hook_content = """
def main(project_list, **kwargs):
    project_list.append(kwargs.get("yes"))
"""
    hook_file.write_text(hook_content)

    hook = hooks.RepoHook(
        hook_type="pre-upload",
        hooks_project=FakeProject(str(tmp_path)),
        repo_topdir=str(tmp_path),
        manifest_url="https://gerrit",
        allow_all_hooks=True,
        yes=yes_val,
    )

    project_list = []
    res = hook.Run(project_list=project_list, worktree_list=[])

    assert res is True
    assert project_list == [yes_val]


@pytest.mark.parametrize("fix_val", (True, False))
def test_repo_upload_fix_arg(tmp_path: Path, fix_val: bool) -> None:
    """Test that fix is passed in kwargs during hook execution."""

    class FakeProject:
        def __init__(self, worktree: str) -> None:
            self.worktree = worktree
            self.enabled_repo_hooks = ["pre-upload"]
            self.config = None

    hook_file = tmp_path / "pre-upload.py"

    hook_content = """
def main(project_list, **kwargs):
    project_list.append(kwargs.get("fix"))
"""
    hook_file.write_text(hook_content)

    hook = hooks.RepoHook(
        hook_type="pre-upload",
        hooks_project=FakeProject(str(tmp_path)),
        repo_topdir=str(tmp_path),
        manifest_url="https://gerrit",
        allow_all_hooks=True,
        fix=fix_val,
    )

    project_list = []
    res = hook.Run(project_list=project_list, worktree_list=[])

    assert res is True
    assert project_list == [fix_val]


def test_from_subcmd_without_fix_option() -> None:
    """Test that FromSubcmd works when opt does not have fix attribute."""

    class Remote:
        url = "https://gerrit"

    class FakeManifest:
        repo_hooks_project = None
        topdir = "/fake/topdir"

        class manifestProject:
            @staticmethod
            def GetRemote(name: str) -> "Remote":
                return Remote()

        class contactinfo:
            bugurl = "https://bugs"

    class FakeOpt:
        bypass_hooks = False
        allow_all_hooks = False
        ignore_hooks = False

    hook = hooks.RepoHook.FromSubcmd(FakeManifest(), FakeOpt(), "post-sync")
    assert hook._fix is False
