#!/usr/bin/env python3
# Copyright: 2026, Maximiliano Curia <maxy@debian.org>
#
# License: ISC
#  Permission to use, copy, modify, and/or distribute this software for any
#  purpose with or without fee is hereby granted, provided that the above
#  copyright notice and this permission notice appear in all copies.
#  .
#  THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
#  REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
#  AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
#  INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
#  LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
#  OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
#  PERFORMANCE OF THIS SOFTWARE.

"""Tests for CopyrightHolder class extraction to core_types.py"""

import unittest

try:
    from decopy.common.core_types import CopyrightHolder, YearRange
except ImportError as e:
    msg = "Cannot import CopyrightHolder from core_types module"
    raise ImportError(msg) from e


class TestCopyrightHolderClass(unittest.TestCase):
    """Test CopyrightHolder class functionality in core_types module"""

    def setUp(self):
        """Set up test fixtures"""
        self.years = YearRange(2020, 2023)

    def test_copyright_holder_creation_with_years(self):
        """Test CopyrightHolder creation with name, email, and years"""
        holder = CopyrightHolder("Test Name", "test@example.com", self.years)
        self.assertIsNotNone(holder)
        self.assertEqual(holder.name, "Test Name")
        self.assertEqual(holder.email, "test@example.com")
        self.assertIs(holder.years, self.years)

    def test_copyright_holder_creation_without_years(self):
        """Test CopyrightHolder creation without years"""
        holder = CopyrightHolder("Test Name", "test@example.com")
        self.assertIsNotNone(holder)
        self.assertEqual(holder.name, "Test Name")
        self.assertEqual(holder.email, "test@example.com")
        self.assertIsNotNone(holder.years)  # Should have a default YearRange object
        self.assertEqual(holder.years.low, 0)  # Default value

    def test_copyright_holder_string_representation(self):
        """Test CopyrightHolder string representation"""
        # With years as YearRange object
        holder_with_years = CopyrightHolder("Test Name", "test@example.com", self.years)
        str_with_years = str(holder_with_years)
        self.assertIn("Test Name", str_with_years)
        self.assertIn("test@example.com", str_with_years)
        self.assertIn("2020-2023", str_with_years)

        # Without years
        holder_without_years = CopyrightHolder("Test Name", "test@example.com")
        str_without_years = str(holder_without_years)
        self.assertIn("Test Name", str_without_years)
        self.assertIn("test@example.com", str_without_years)
        self.assertNotIn("2020", str_without_years)

        # With years as string
        holder_with_string_years = CopyrightHolder(
            "Test Name",
            "test@example.com",
            YearRange(low=2021, high=2022),
        )
        str_with_string_years = str(holder_with_string_years)
        self.assertIn("Test Name", str_with_string_years)
        self.assertIn("test@example.com", str_with_string_years)
        self.assertIn("2021-2022", str_with_string_years)

    def test_copyright_holder_tuple_representation(self):
        """Test CopyrightHolder tuple representation"""
        # With years as YearRange object
        holder_with_years = CopyrightHolder("Test Name", "test@example.com", self.years)
        tuple_with_years = holder_with_years.as_tuple()
        self.assertIn("Test Name", tuple_with_years)
        self.assertIn("test@example.com", tuple_with_years)
        self.assertIn("2020-2023", tuple_with_years)

        # Without years
        holder_without_years = CopyrightHolder("Test Name", "test@example.com")
        tuple_without_years = holder_without_years.as_tuple()
        self.assertIn("Test Name", tuple_without_years)
        self.assertIn("test@example.com", tuple_without_years)
        self.assertNotIn("2020", tuple_without_years)

        # With years as string
        holder_with_string_years = CopyrightHolder(
            "Test Name",
            "test@example.com",
            YearRange(2021, 2022),
        )
        tuple_with_string_years = holder_with_string_years.as_tuple()
        self.assertIn("Test Name", tuple_with_string_years)
        self.assertIn("test@example.com", tuple_with_string_years)
        self.assertIn("2021-2022", tuple_with_string_years)

    def test_copyright_holder_properties(self):
        """Test CopyrightHolder properties"""
        holder = CopyrightHolder("Test Name", "test@example.com", self.years)

        # Test name property
        self.assertEqual(holder.name, "Test Name")

        # Test email property
        self.assertEqual(holder.email, "test@example.com")

        # Test years property
        self.assertIs(holder.years, self.years)

    def test_copyright_holder_years_property_can_be_none(self):
        """Test that CopyrightHolder years property can be None"""
        holder = CopyrightHolder("Test Name", "test@example.com", None)
        # When None is explicitly passed, it gets converted to default YearRange
        self.assertIsNotNone(holder.years)
        self.assertEqual(str(holder.years), "")  # Empty YearRange string representation

    def test_copyright_holder_years_property_with_value(self):
        """Test that CopyrightHolder years property works with YearRange"""
        holder = CopyrightHolder("Test Name", "test@example.com", self.years)
        self.assertIsNotNone(holder.years)
        self.assertEqual(holder.years.low, 2020)
        self.assertEqual(holder.years.high, 2023)

    def test_multiple_copyright_holder_instances(self):
        """Test creating multiple CopyrightHolder instances"""
        holders = [
            CopyrightHolder("Alice", "alice@example.com", self.years),
            CopyrightHolder("Bob", "bob@example.com"),
            CopyrightHolder("Charlie", "charlie@example.com", YearRange(2021, 2022)),
        ]

        # All should be different instances
        self.assertEqual(len(holders), 3)

        # Test they maintain correct values
        self.assertEqual(holders[0].name, "Alice")
        self.assertEqual(holders[0].email, "alice@example.com")
        self.assertEqual(holders[1].name, "Bob")
        self.assertEqual(holders[1].email, "bob@example.com")
        self.assertEqual(holders[2].name, "Charlie")
        self.assertEqual(holders[2].email, "charlie@example.com")

    def test_copyright_holder_with_years(self):
        """Test CopyrightHolder creation with years"""
        years = YearRange(2020, 2023)
        holder = CopyrightHolder("Test Name", "test@example.com", years)
        self.assertIsNotNone(holder.years)
        self.assertEqual(str(holder.years), "2020-2023")  # Should be the string itself

    def test_copyright_holder_with_single_year(self):
        """Test CopyrightHolder creation with single year"""
        year = YearRange(2020)
        holder = CopyrightHolder("Test Name", "test@example.com", year)
        self.assertIsNotNone(holder.years)
        self.assertEqual(str(holder.years), "2020")  # Should be the string itself

    def test_copyright_holder_with_integer_years(self):
        """Test CopyrightHolder creation with integer years"""
        single_year = YearRange(2020)
        holder = CopyrightHolder("Test Name", "test@example.com", single_year)
        self.assertIsNotNone(holder.years)
        self.assertEqual(
            str(holder.years),
            "2020",
        )  # Should be the string representation

    def test_copyright_holder_with_yearrange_object(self):
        """Test CopyrightHolder creation with YearRange object"""
        year_range = YearRange(2020, 2023)
        holder = CopyrightHolder("Test Name", "test@example.com", year_range)
        self.assertIsNotNone(holder.years)
        self.assertEqual(holder.years.low, 2020)
        self.assertEqual(holder.years.high, 2023)
        self.assertIs(holder.years, year_range)  # Should be the same object

    def test_copyright_holder_years_are_optional(self):
        """Test that years parameter is truly optional"""
        holder1 = CopyrightHolder("Name1", "email1@example.com")
        holder2 = CopyrightHolder("Name2", "email2@example.com", None)
        holder3 = CopyrightHolder("Name3", "email3@example.com")

        # All should have default YearRange objects
        self.assertIsNotNone(holder1.years)
        self.assertIsNotNone(holder2.years)
        self.assertIsNotNone(holder3.years)
        # All should have the same default value
        self.assertEqual(holder1.years.low, 0)
        self.assertEqual(holder2.years.low, 0)
        self.assertEqual(holder3.years.low, 0)

    def test_copyright_holder_different_name_email_combinations(self):
        """Test CopyrightHolder with various name and email combinations"""
        test_cases = [
            ("Full Name", "full@example.com"),
            ("Short", "short@example.com"),
            ("Name With Spaces", "name.with.spaces@example.com"),
            ("Unicode Name", "unicode@example.com"),
            ("", ""),  # Empty strings
        ]

        for name, email in test_cases:
            holder = CopyrightHolder(name, email)
            self.assertEqual(holder.name, name)
            self.assertEqual(holder.email, email)


if __name__ == "__main__":
    unittest.main()
