# Copyright (C) 2024 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 color.py module."""

from unittest import mock

import pytest
import utils_for_test

import color
import git_config


@pytest.fixture
def coloring() -> color.Coloring:
    """Create a Coloring object for testing."""
    return _make_coloring("always")


def _make_coloring(default_state: str) -> color.Coloring:
    """Set the default color mode and return a Coloring using test config."""
    config_fixture = utils_for_test.FIXTURES_DIR / "test.gitconfig"
    config = git_config.GitConfig(config_fixture)
    color.SetDefaultColoring(default_state)
    return color.Coloring(config, "status")


def test_Color_Parse_all_params_none(coloring: color.Coloring) -> None:
    """all params are None"""
    val = coloring._parse(None, None, None, None)
    assert val == ""


def test_Color_Parse_first_parameter_none(coloring: color.Coloring) -> None:
    """check fg & bg & attr"""
    val = coloring._parse(None, "black", "red", "ul")
    assert val == "\x1b[4;30;41m"


def test_Color_Parse_one_entry(coloring: color.Coloring) -> None:
    """check fg"""
    val = coloring._parse("one", None, None, None)
    assert val == "\033[33m"


def test_Color_Parse_two_entry(coloring: color.Coloring) -> None:
    """check fg & bg"""
    val = coloring._parse("two", None, None, None)
    assert val == "\033[35;46m"


def test_Color_Parse_three_entry(coloring: color.Coloring) -> None:
    """check fg & bg & attr"""
    val = coloring._parse("three", None, None, None)
    assert val == "\033[4;30;41m"


def test_Color_Parse_reset_entry(coloring: color.Coloring) -> None:
    """check reset entry"""
    val = coloring._parse("reset", None, None, None)
    assert val == "\033[m"


def test_Color_Parse_empty_entry(coloring: color.Coloring) -> None:
    """check empty entry"""
    val = coloring._parse("none", "blue", "white", "dim")
    assert val == "\033[2;34;47m"
    val = coloring._parse("empty", "green", "white", "bold")
    assert val == "\033[1;32;47m"


class TestSetDefaultColoring:
    """Tests for SetDefaultColoring."""

    def test_none_leaves_default_unchanged(self) -> None:
        color.DEFAULT = "auto"
        color.SetDefaultColoring(None)
        assert color.DEFAULT == "auto"

    @pytest.mark.parametrize(
        "value, expected",
        (
            # auto/true/yes all store their lowercase form.
            ("auto", "auto"),
            ("Auto", "auto"),
            ("true", "true"),
            ("True", "true"),
            ("yes", "yes"),
            ("Yes", "yes"),
            # "always" stores as "always".
            ("always", "always"),
            ("Always", "always"),
            # never/no/false store their lowercase form.
            ("never", "never"),
            ("no", "no"),
            ("false", "false"),
        ),
    )
    def test_maps_to_expected(self, value: str, expected: str) -> None:
        color.SetDefaultColoring(value)
        assert color.DEFAULT == expected

    def test_unrecognised_leaves_default_unchanged(self) -> None:
        color.DEFAULT = "auto"
        color.SetDefaultColoring("garbage")
        assert color.DEFAULT == "auto"


class TestColoringInit:
    """Tests for Coloring.__init__ color mode logic."""

    @pytest.mark.parametrize(
        "state, isatty, pager_active, expected",
        (
            # "always" enables color unconditionally.
            ("always", False, False, True),
            # "never" disables color unconditionally.
            ("never", True, True, False),
            # auto/true/yes enable color only on a TTY or active pager.
            ("auto", True, False, True),
            ("auto", False, False, False),
            ("auto", False, True, True),
            ("true", True, False, True),
            ("true", False, False, False),
            ("true", False, True, True),
            ("yes", True, False, True),
            ("yes", False, False, False),
            ("yes", False, True, True),
        ),
    )
    def test_color_mode(
        self,
        state: str,
        isatty: bool,
        pager_active: bool,
        expected: bool,
    ) -> None:
        with mock.patch("os.isatty", return_value=isatty), mock.patch(
            "pager.active", pager_active
        ):
            c = _make_coloring(state)
        assert c.is_on is expected
