import pytest
import copy
from merge_log4j2_yaml import deep_merge, merge_named_lists, merge_appenders

def test_merge_named_lists_basic():
    base = [
        {'name': 'A', 'val': 1},
        {'name': 'B', 'val': 2}
    ]
    override = [
        {'name': 'B', 'val': 3},
        {'name': 'C', 'val': 4}
    ]
    result = merge_named_lists(base, override, key_name='name')
    assert any(item['name'] == 'A' and item['val'] == 1 for item in result)
    assert any(item['name'] == 'B' and item['val'] == 3 for item in result)
    assert any(item['name'] == 'C' and item['val'] == 4 for item in result)
    assert len(result) == 3

def test_merge_named_lists_single_dict_vs_list():
    base = {'name': 'A', 'val': 1}
    override = [{'name': 'A', 'val': 2}, {'name': 'B', 'val': 3}]
    result = merge_named_lists([base], override, key_name='name')
    assert any(item['name'] == 'A' and item['val'] == 2 for item in result)
    assert any(item['name'] == 'B' and item['val'] == 3 for item in result)
    assert len(result) == 2

def test_merge_appenders_multiple_types():
    base = {
        'Console': [{'name': 'stdout', 'target': 'SYSTEM_OUT'}],
        'File': {'name': 'file1', 'fileName': 'logs/file1.log'}
    }
    override = {
        'Console': [{'name': 'CONSOLE', 'target': 'SYSTEM_OUT'}],
        'File': [{'name': 'file1', 'fileName': 'logs/file1-override.log'}, {'name': 'file2', 'fileName': 'logs/file2.log'}]
    }
    result = merge_appenders(base, override)
    assert any(app['name'] == 'stdout' for app in result['Console'])
    assert any(app['name'] == 'CONSOLE' for app in result['Console'])
    assert any(app['name'] == 'file1' and app['fileName'] == 'logs/file1-override.log' for app in result['File'])
    assert any(app['name'] == 'file2' for app in result['File'])
    assert len(result['File']) == 2

def test_deep_merge_loggers():
    base = {
        'Logger': [
            {'name': 'org.example', 'level': 'INFO'},
            {'name': 'org.apache', 'level': 'WARN'}
        ]
    }
    override = {
        'Logger': [
            {'name': 'org.example', 'level': 'DEBUG'},
            {'name': 'org.new', 'level': 'TRACE'}
        ]
    }
    result = deep_merge(base, override)
    names = [l['name'] for l in result['Logger']]
    assert 'org.example' in names
    assert 'org.apache' in names
    assert 'org.new' in names
    for l in result['Logger']:
        if l['name'] == 'org.example':
            assert l['level'] == 'DEBUG'

def test_deep_merge_missing_sections():
    base = {'A': 1, 'B': {'C': 2}}
    override = {'B': {'D': 3}, 'E': 4}
    result = deep_merge(base, override)
    assert result['A'] == 1
    assert result['B']['C'] == 2
    assert result['B']['D'] == 3
    assert result['E'] == 4

def test_merge_named_lists_no_name():
    base = [{'id': 1, 'val': 10}]
    override = [{'id': 2, 'val': 20}]
    # Should concatenate since 'name' is missing
    result = merge_named_lists(base, override, key_name='name')
    assert len(result) == 2
    assert any(item['id'] == 1 for item in result)
    assert any(item['id'] == 2 for item in result)

def test_merge_named_lists_scalars():
    base = [1, 2, 3]
    override = [4, 5]
    result = merge_named_lists(base, override, key_name='name')
    assert result == [1, 2, 3, 4, 5]

def test_deep_merge_nested_dicts():
    base = {'A': {'B': {'C': 1}}}
    override = {'A': {'B': {'D': 2}}}
    result = deep_merge(base, override)
    assert result['A']['B']['C'] == 1
    assert result['A']['B']['D'] == 2
