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

import pytest
from unittest.mock import patch

from shared import MOCK_OS_INFO
from sun.configs import Configs


class TestConfigs:

    def test_valid_config(self):
        config = Configs()
        assert config.interval == 720
        assert config.standby == 5
        assert config.repo_log_file == 'ChangeLog.txt'
        assert config.repo_mirror == 'https://mirrors.slackware.com/slackware/slackware64-15.0/'
        assert config.delay_load == 5
        assert config.max_packages == 10
        assert config.badge_interval == 180
        assert config.colored_output is True
        assert config.log_font_size == 10
        assert config.notifications is True
        assert config.http_timeout == 30

    def test_colored_output_false(self, tmp_path):
        conf = tmp_path / 'sun.conf'
        conf.write_text(
            '[REPOSITORY]\nHTTP_MIRROR = http://example.com/\nLOG_PATH = /tmp/\nLOG_FILE = ChangeLog.txt\n'
            '[TIME]\nINTERVAL = 720\nSTANDBY = 5\n'
            '[TRAY_ICON]\nDELAY_LOAD = 5\nMAX_PACKAGES = 10\nCOLORED_OUTPUT = false\n',
            encoding='utf-8'
        )
        info = {**MOCK_OS_INFO, 'sun_conf_path': tmp_path}
        with patch('sun.configs.get_static_paths', return_value=info):
            config = Configs()
        assert config.colored_output is False

    def test_badge_interval_fallback(self, tmp_path):
        conf = tmp_path / 'sun.conf'
        conf.write_text(
            '[REPOSITORY]\nHTTP_MIRROR = http://example.com/\nLOG_PATH = /tmp/\nLOG_FILE = ChangeLog.txt\n'
            '[TIME]\nINTERVAL = 720\nSTANDBY = 5\n'
            '[TRAY_ICON]\nDELAY_LOAD = 5\nMAX_PACKAGES = 10\n',
            encoding='utf-8'
        )
        info = {**MOCK_OS_INFO, 'sun_conf_path': tmp_path}
        with patch('sun.configs.get_static_paths', return_value=info):
            config = Configs()
        assert config.badge_interval == 180

    def test_notifications_false(self, tmp_path):
        conf = tmp_path / 'sun.conf'
        conf.write_text(
            '[REPOSITORY]\nHTTP_MIRROR = http://example.com/\nLOG_PATH = /tmp/\nLOG_FILE = ChangeLog.txt\n'
            '[TIME]\nINTERVAL = 720\nSTANDBY = 5\nNOTIFICATIONS = false\n'
            '[TRAY_ICON]\nDELAY_LOAD = 5\nMAX_PACKAGES = 10\n',
            encoding='utf-8'
        )
        info = {**MOCK_OS_INFO, 'sun_conf_path': tmp_path}
        with patch('sun.configs.get_static_paths', return_value=info):
            config = Configs()
        assert config.notifications is False

    def test_http_timeout_fallback(self, tmp_path):
        conf = tmp_path / 'sun.conf'
        conf.write_text(
            '[REPOSITORY]\nHTTP_MIRROR = http://example.com/\nLOG_PATH = /tmp/\nLOG_FILE = ChangeLog.txt\n'
            '[TIME]\nINTERVAL = 720\nSTANDBY = 5\n'
            '[TRAY_ICON]\nDELAY_LOAD = 5\nMAX_PACKAGES = 10\n',
            encoding='utf-8'
        )
        info = {**MOCK_OS_INFO, 'sun_conf_path': tmp_path}
        with patch('sun.configs.get_static_paths', return_value=info):
            config = Configs()
        assert config.http_timeout == 30

    def test_notifications_fallback(self, tmp_path):
        conf = tmp_path / 'sun.conf'
        conf.write_text(
            '[REPOSITORY]\nHTTP_MIRROR = http://example.com/\nLOG_PATH = /tmp/\nLOG_FILE = ChangeLog.txt\n'
            '[TIME]\nINTERVAL = 720\nSTANDBY = 5\n'
            '[TRAY_ICON]\nDELAY_LOAD = 5\nMAX_PACKAGES = 10\n',
            encoding='utf-8'
        )
        info = {**MOCK_OS_INFO, 'sun_conf_path': tmp_path}
        with patch('sun.configs.get_static_paths', return_value=info):
            config = Configs()
        assert config.notifications is True

    def test_log_font_size_fallback(self, tmp_path):
        conf = tmp_path / 'sun.conf'
        conf.write_text(
            '[REPOSITORY]\nHTTP_MIRROR = http://example.com/\nLOG_PATH = /tmp/\nLOG_FILE = ChangeLog.txt\n'
            '[TIME]\nINTERVAL = 720\nSTANDBY = 5\n'
            '[TRAY_ICON]\nDELAY_LOAD = 5\nMAX_PACKAGES = 10\n',
            encoding='utf-8'
        )
        info = {**MOCK_OS_INFO, 'sun_conf_path': tmp_path}
        with patch('sun.configs.get_static_paths', return_value=info):
            config = Configs()
        assert config.log_font_size == 10

    def test_ignore_mirror_warning_true(self, tmp_path):
        conf = tmp_path / 'sun.conf'
        conf.write_text(
            '[REPOSITORY]\nHTTP_MIRROR = http://example.com/\nLOG_PATH = /tmp/\nLOG_FILE = ChangeLog.txt\n'
            'IGNORE_MIRROR_WARNING = true\n'
            '[TIME]\nINTERVAL = 720\nSTANDBY = 5\n'
            '[TRAY_ICON]\nDELAY_LOAD = 5\nMAX_PACKAGES = 10\n',
            encoding='utf-8'
        )
        info = {**MOCK_OS_INFO, 'sun_conf_path': tmp_path}
        with patch('sun.configs.get_static_paths', return_value=info):
            config = Configs()
        assert config.ignore_mirror_warning is True

    def test_ignore_mirror_warning_fallback(self, tmp_path):
        conf = tmp_path / 'sun.conf'
        conf.write_text(
            '[REPOSITORY]\nHTTP_MIRROR = http://example.com/\nLOG_PATH = /tmp/\nLOG_FILE = ChangeLog.txt\n'
            '[TIME]\nINTERVAL = 720\nSTANDBY = 5\n'
            '[TRAY_ICON]\nDELAY_LOAD = 5\nMAX_PACKAGES = 10\n',
            encoding='utf-8'
        )
        info = {**MOCK_OS_INFO, 'sun_conf_path': tmp_path}
        with patch('sun.configs.get_static_paths', return_value=info):
            config = Configs()
        assert config.ignore_mirror_warning is False

    def test_colored_output_fallback(self, tmp_path):
        conf = tmp_path / 'sun.conf'
        conf.write_text(
            '[REPOSITORY]\nHTTP_MIRROR = http://example.com/\nLOG_PATH = /tmp/\nLOG_FILE = ChangeLog.txt\n'
            '[TIME]\nINTERVAL = 720\nSTANDBY = 5\n'
            '[TRAY_ICON]\nDELAY_LOAD = 5\nMAX_PACKAGES = 10\n',
            encoding='utf-8'
        )
        info = {**MOCK_OS_INFO, 'sun_conf_path': tmp_path}
        with patch('sun.configs.get_static_paths', return_value=info):
            config = Configs()
        assert config.colored_output is True

    def test_missing_config_file(self, tmp_path):
        missing_info = {**MOCK_OS_INFO, 'sun_conf_path': tmp_path / 'nonexistent'}
        with patch('sun.configs.get_static_paths', return_value=missing_info):
            with pytest.raises(SystemExit):
                Configs()

    def test_malformed_config_missing_key(self, tmp_path):
        conf = tmp_path / 'sun.conf'
        conf.write_text('[TIME]\nINTERVAL = 720\n', encoding='utf-8')
        broken_info = {**MOCK_OS_INFO, 'sun_conf_path': tmp_path}
        with patch('sun.configs.get_static_paths', return_value=broken_info):
            with pytest.raises(SystemExit):
                Configs()

    @pytest.mark.parametrize('key,value', [
        ('INTERVAL', '0'),
        ('INTERVAL', '-1'),
        ('STANDBY', '0'),
        ('STANDBY', '-1'),
        ('DELAY_LOAD', '-1'),
        ('MAX_PACKAGES', '0'),
        ('MAX_PACKAGES', '-1'),
        ('BADGE_INTERVAL', '0'),
        ('BADGE_INTERVAL', '-1'),
        ('LOG_FONT_SIZE', '0'),
        ('LOG_FONT_SIZE', '-1'),
        ('HTTP_TIMEOUT', '0'),
        ('HTTP_TIMEOUT', '-1'),
    ])
    def test_invalid_config_values(self, tmp_path, key, value):
        conf = tmp_path / 'sun.conf'
        defaults = {
            'INTERVAL': '720', 'STANDBY': '5', 'DELAY_LOAD': '5',
            'MAX_PACKAGES': '10', 'BADGE_INTERVAL': '180', 'LOG_FONT_SIZE': '10',
            'HTTP_TIMEOUT': '30',
        }
        base = (
            f'[REPOSITORY]\nHTTP_MIRROR = http://example.com/\nLOG_PATH = /tmp/\n'
            f'LOG_FILE = ChangeLog.txt\nHTTP_TIMEOUT = 30\n'
            f'[TIME]\nINTERVAL = 720\nSTANDBY = 5\n'
            f'[TRAY_ICON]\nDELAY_LOAD = 5\nMAX_PACKAGES = 10\nBADGE_INTERVAL = 180\nLOG_FONT_SIZE = 10\n'
        )
        conf.write_text(
            base.replace(f'{key} = {defaults[key]}', f'{key} = {value}'),
            encoding='utf-8'
        )
        broken_info = {**MOCK_OS_INFO, 'sun_conf_path': tmp_path}
        with patch('sun.configs.get_static_paths', return_value=broken_info):
            with pytest.raises(SystemExit):
                Configs()

    def test_data_configs_set(self):
        config = Configs()
        assert config.data_configs['pkg_path'] is not None

    def test_colors_defined(self):
        from sun.cli import Cli
        assert Cli.bold
        assert Cli.green
        assert Cli.endc
