from unittest.mock import call, MagicMock, patch

from schmetterling.build.maven import build_multi_modules
from schmetterling.build.maven import create_build_result
from schmetterling.build.maven import create_command
from schmetterling.build.maven import create_multi_modules
from schmetterling.build.maven import create_state
from schmetterling.build.maven import get_maven_infos
from schmetterling.build.maven import get_maven_repos
from schmetterling.build.maven import get_multi_modules
from schmetterling.build.state import BuildState, Build
from schmetterling.setup.state import Repo


def test_build_multi_modules():
    mm = [
        {
            'updated': 'updated1',
            'pom_dir': 'pom_dir1',
            'coordinates': 'coordinates1'
        },
        {
            'updated': 'updated2',
            'pom_dir': 'pom_dir2',
            'coordinates': 'coordinates2'
        },
    ]
    with patch(
            'schmetterling.build.maven.create_command',
            return_value='create_command') as m_create_command, patch(
        'schmetterling.build.maven.run_command') as m_run_command, patch(
        'schmetterling.build.maven.create_build_result',
        return_value=[['success_coordinates'], [
            'failure_coordinates'
        ]]) as m_create_build_result:
        assert (
                   ['success_coordinates', 'success_coordinates'],
                   ['failure_coordinates', 'failure_coordinates'],
               ) == build_multi_modules(mm, 'repository_dir', 'settings_file', 'logback_file')
        assert [
                   call('updated1', 'pom_dir1/mvn.log', 'repository_dir', 'settings_file', 'logback_file'),
                   call('updated2', 'pom_dir2/mvn.log', 'repository_dir', 'settings_file', 'logback_file')
               ] == m_create_command.mock_calls
        assert [
                   call('create_command', cwd='pom_dir1'),
                   call('create_command', cwd='pom_dir2')
               ] == m_run_command.mock_calls
        assert [
                   call('coordinates1', 'updated1', 'pom_dir1/mvn.log'),
                   call('coordinates2', 'updated2', 'pom_dir2/mvn.log')
               ] == m_create_build_result.mock_calls


def test_create_command():
    assert str('mvn -Dmaven.repo.local=repository '
               '-s settings.xml '
               '-DcreateChecksum=true '
               '-Dfile.encoding=UTF-8 '
               '-Dsun.jnu.encoding=UTF-8 '
               '-Dlogback.configurationFile=logback.xml '
               '-B -amd -pl mygroup:app.admin,mygroup:app.sign '
               'clean install javadoc:jar source:jar '
               '--fail-at-end | tee mvn.log') == create_command(
        [{
            'artifact_id': 'app.admin',
            'group_id': 'mygroup',
        }, {
            'artifact_id': 'app.sign',
            'group_id': 'mygroup',
        }], 'mvn.log', 'repository', 'settings.xml', 'logback.xml')


@patch(
    'schmetterling.build.maven.get_summary',
    return_value=(['mygroup:app.admin'], ['app.sign']))
def test_create_build_result(mock_get_summary):
    assert (
               [
                   {
                       'artifact_id': 'app.admin',
                       'group_id': 'mygroup',
                   },
               ],
               [
                   {
                       'artifact_id': 'app.sign',
                       'group_id': 'mygroup',
                   },
                   {
                       'artifact_id': 'pipeline.env',
                       'group_id': 'mygroup',
                   },
               ],
           ) == create_build_result(
        [
            {
                'artifact_id': 'app.admin',
                'group_id': 'mygroup',
            },
            {
                'artifact_id': 'app.sign',
                'group_id': 'mygroup',
            },
            {
                'artifact_id': 'pipeline.env',
                'group_id': 'mygroup',
            },
            {
                'artifact_id': 'xml.ws',
                'group_id': 'mygroup',
            },
        ],
        [
            {
                'artifact_id': 'app.admin',
                'group_id': 'mygroup',
            },
            {
                'artifact_id': 'app.sign',
                'group_id': 'mygroup',
            },
            {
                'artifact_id': 'pipeline.env',
                'group_id': 'mygroup',
            },
        ],
        'mvn.log',
    )


def test_create_multi_modules():
    with patch('schmetterling.build.maven.makedirs') as m, patch(
            'schmetterling.build.maven.open') as o:
        f = MagicMock()
        o.return_value = MagicMock(__enter__=MagicMock(return_value=f))

        create_multi_modules([
            {
                'pom_dir': 'pd1',
                'pom_content': 'pc1'
            },
            {
                'pom_dir': 'pd2',
                'pom_content': 'pc2'
            },
        ])
        assert [call('pd1', exist_ok=True),
                call('pd2', exist_ok=True)] == m.mock_calls
        assert [call.write('pc1'), call.write('pc2')] == f.mock_calls


def test_create_state():
    state = BuildState('schmetterling.build.maven',
                       [
                           Build('mygroup', 'app.admin', '0.0.1-SNAPSHOT', 'app.admin',
                                 Build.SUCCESS, 1),
                           Build('mygroup', 'pipeline-apache-proxy', '1.0.0-SNAPSHOT',
                                 'pipeline-apache-proxy', Build.FAILURE, 1),
                       ])
    assert state == create_state(
        [],
        [{
            'pom_path': 'app.admin/pom.xml',
            'artifact_id': 'app.admin',
            'group_id': 'mygroup',
            'version': '0.0.1-SNAPSHOT',
            'packaging': 'jar'
        }],
        [{
            'pom_path': 'pipeline-apache-proxy/pom.xml',
            'artifact_id': 'pipeline-apache-proxy',
            'group_id': 'mygroup',
            'version': '1.0.0-SNAPSHOT',
            'packaging': 'jar'
        }],
        1,
    )


def test_get_maven_info():
    with patch('schmetterling.build.maven.get_pom_info', side_effect=lambda x: x):
        repos = [
            MagicMock(status=Repo.STATUS_UPDATED, path='path1'),
            MagicMock(status=Repo.STATUS_UNCHANGED, path='path2'),
        ]
        assert [(True, 'path1/pom.xml'),
                (False, 'path2/pom.xml')] == get_maven_infos(repos)


def test_get_maven_repos():
    with patch('schmetterling.build.maven.isinstance', return_value=True):
        with patch('schmetterling.build.maven.exists', side_effect=[False, True]):
            m = MagicMock(path='pom_repo', return_value='pom_repo')
            state = [MagicMock(repos=[
                MagicMock(path='non_pom_repo'),
                m,
            ])]
            assert [m] == get_maven_repos(state)


def test_get_multi_modules():
    with patch('schmetterling.build.maven.get_pom', return_value='pom_content'):
        assert [] == get_multi_modules([(False, {})], 'build_dir')
        assert [{
            'coordinates': [{}],
            'pom_content': 'pom_content',
            'pom_dir': 'build_dir/jar-modules',
            'updated': [{}]
        }] == get_multi_modules([(True, {})], 'build_dir')
        assert [{
            'coordinates': [{
                'packaging': 'jar'
            }],
            'pom_content': 'pom_content',
            'pom_dir': 'build_dir/jar-modules',
            'updated': [{
                'packaging': 'jar'
            }]
        }] == get_multi_modules([(True, {
            'packaging': 'jar'
        })], 'build_dir')
        assert [{
            'coordinates': [{
                'artifact_id': 'super-pom',
                'packaging': 'pom'
            }],
            'pom_content':
                'pom_content',
            'pom_dir':
                'build_dir/super-pom-modules',
            'updated': [{
                'artifact_id': 'super-pom',
                'packaging': 'pom'
            }]
        }] == get_multi_modules([(True, {
            'artifact_id': 'super-pom',
            'packaging': 'pom'
        })], 'build_dir')
        assert [{
            'coordinates': [{
                'artifact_id': 'pom',
                'packaging': 'pom'
            }],
            'pom_content': 'pom_content',
            'pom_dir': 'build_dir/pom-pom-modules',
            'updated': [{
                'artifact_id': 'pom',
                'packaging': 'pom'
            }]
        }] == get_multi_modules([(True, {
            'artifact_id': 'pom',
            'packaging': 'pom'
        })], 'build_dir')
        assert [{
            'coordinates': [{
                'artifact_id': 'x',
                'packaging': 'x'
            }],
            'pom_content': 'pom_content',
            'pom_dir': 'build_dir/other-modules',
            'updated': [{
                'artifact_id': 'x',
                'packaging': 'x'
            }]
        }] == get_multi_modules([(True, {
            'artifact_id': 'x',
            'packaging': 'x'
        })], 'build_dir')
        assert [{
            'coordinates': [{
                'artifact_id': 'war',
                'packaging': 'war'
            }],
            'pom_content': 'pom_content',
            'pom_dir': 'build_dir/war-modules',
            'updated': [{
                'artifact_id': 'war',
                'packaging': 'war'
            }]
        }] == get_multi_modules([(True, {
            'artifact_id': 'war',
            'packaging': 'war'
        })], 'build_dir')
        assert [{
            'coordinates': [{
                'artifact_id': 'jar1',
                'packaging': 'jar'
            }, {
                'artifact_id': 'jar2'
            }, {
                'artifact_id': 'jar3'
            }],
            'pom_content':
                'pom_content',
            'pom_dir':
                'build_dir/jar-modules',
            'updated': [{
                'artifact_id': 'jar1',
                'packaging': 'jar'
            }, {
                'artifact_id': 'jar2'
            }]
        }, {
            'coordinates': [{
                'artifact_id': 'war',
                'packaging': 'war'
            }],
            'pom_content': 'pom_content',
            'pom_dir': 'build_dir/war-modules',
            'updated': [{
                'artifact_id': 'war',
                'packaging': 'war'
            }]
        }] == get_multi_modules([(True, {
            'artifact_id': 'jar1',
            'packaging': 'jar'
        }), (True, {
            'artifact_id': 'jar2'
        }), (False, {
            'artifact_id': 'jar3'
        }), (True, {
            'artifact_id': 'war',
            'packaging': 'war'
        })], 'build_dir')

[(73, 'unittest.mock.patch', 'patch', (['"""schmetterling.build.maven.get_summary"""'], {'return_value': "(['mygroup:app.admin'], ['app.sign'])"}), False, 'from unittest.mock import call, MagicMock, patch\n'), (28, 'unittest.mock.patch', 'patch', (['"""schmetterling.build.maven.create_command"""'], {'return_value': '"""create_command"""'}), False, 'from unittest.mock import call, MagicMock, patch\n'), (30, 'unittest.mock.patch', 'patch', (['"""schmetterling.build.maven.run_command"""'], {}), False, 'from unittest.mock import call, MagicMock, patch\n'), (31, 'unittest.mock.patch', 'patch', (['"""schmetterling.build.maven.create_build_result"""'], {'return_value': "[['success_coordinates'], ['failure_coordinates']]"}), False, 'from unittest.mock import call, MagicMock, patch\n'), (63, 'schmetterling.build.maven.create_command', 'create_command', (["[{'artifact_id': 'app.admin', 'group_id': 'mygroup'}, {'artifact_id':\n    'app.sign', 'group_id': 'mygroup'}]", '"""mvn.log"""', '"""repository"""', '"""settings.xml"""', '"""logback.xml"""'], {}), False, 'from schmetterling.build.maven import create_command\n'), (94, 'schmetterling.build.maven.create_build_result', 'create_build_result', (["[{'artifact_id': 'app.admin', 'group_id': 'mygroup'}, {'artifact_id':\n    'app.sign', 'group_id': 'mygroup'}, {'artifact_id': 'pipeline.env',\n    'group_id': 'mygroup'}, {'artifact_id': 'xml.ws', 'group_id': 'mygroup'}]", "[{'artifact_id': 'app.admin', 'group_id': 'mygroup'}, {'artifact_id':\n    'app.sign', 'group_id': 'mygroup'}, {'artifact_id': 'pipeline.env',\n    'group_id': 'mygroup'}]", '"""mvn.log"""'], {}), False, 'from schmetterling.build.maven import create_build_result\n'), (132, 'unittest.mock.patch', 'patch', (['"""schmetterling.build.maven.makedirs"""'], {}), False, 'from unittest.mock import call, MagicMock, patch\n'), (132, 'unittest.mock.patch', 'patch', (['"""schmetterling.build.maven.open"""'], {}), False, 'from unittest.mock import call, MagicMock, patch\n'), (134, 'unittest.mock.MagicMock', 'MagicMock', ([], {}), False, 'from unittest.mock import call, MagicMock, patch\n'), (137, 'schmetterling.build.maven.create_multi_modules', 'create_multi_modules', (["[{'pom_dir': 'pd1', 'pom_content': 'pc1'}, {'pom_dir': 'pd2', 'pom_content':\n    'pc2'}]"], {}), False, 'from schmetterling.build.maven import create_multi_modules\n'), (160, 'schmetterling.build.maven.create_state', 'create_state', (['[]', "[{'pom_path': 'app.admin/pom.xml', 'artifact_id': 'app.admin', 'group_id':\n    'mygroup', 'version': '0.0.1-SNAPSHOT', 'packaging': 'jar'}]", "[{'pom_path': 'pipeline-apache-proxy/pom.xml', 'artifact_id':\n    'pipeline-apache-proxy', 'group_id': 'mygroup', 'version':\n    '1.0.0-SNAPSHOT', 'packaging': 'jar'}]", '(1)'], {}), False, 'from schmetterling.build.maven import create_state\n'), (181, 'unittest.mock.patch', 'patch', (['"""schmetterling.build.maven.get_pom_info"""'], {'side_effect': '(lambda x: x)'}), False, 'from unittest.mock import call, MagicMock, patch\n'), (191, 'unittest.mock.patch', 'patch', (['"""schmetterling.build.maven.isinstance"""'], {'return_value': '(True)'}), False, 'from unittest.mock import call, MagicMock, patch\n'), (202, 'unittest.mock.patch', 'patch', (['"""schmetterling.build.maven.get_pom"""'], {'return_value': '"""pom_content"""'}), False, 'from unittest.mock import call, MagicMock, patch\n'), (39, 'schmetterling.build.maven.build_multi_modules', 'build_multi_modules', (['mm', '"""repository_dir"""', '"""settings_file"""', '"""logback_file"""'], {}), False, 'from schmetterling.build.maven import build_multi_modules\n'), (155, 'schmetterling.build.state.Build', 'Build', (['"""mygroup"""', '"""app.admin"""', '"""0.0.1-SNAPSHOT"""', '"""app.admin"""', 'Build.SUCCESS', '(1)'], {}), False, 'from schmetterling.build.state import BuildState, Build\n'), (157, 'schmetterling.build.state.Build', 'Build', (['"""mygroup"""', '"""pipeline-apache-proxy"""', '"""1.0.0-SNAPSHOT"""', '"""pipeline-apache-proxy"""', 'Build.FAILURE', '(1)'], {}), False, 'from schmetterling.build.state import BuildState, Build\n'), (183, 'unittest.mock.MagicMock', 'MagicMock', ([], {'status': 'Repo.STATUS_UPDATED', 'path': '"""path1"""'}), False, 'from unittest.mock import call, MagicMock, patch\n'), (184, 'unittest.mock.MagicMock', 'MagicMock', ([], {'status': 'Repo.STATUS_UNCHANGED', 'path': '"""path2"""'}), False, 'from unittest.mock import call, MagicMock, patch\n'), (187, 'schmetterling.build.maven.get_maven_infos', 'get_maven_infos', (['repos'], {}), False, 'from schmetterling.build.maven import get_maven_infos\n'), (192, 'unittest.mock.patch', 'patch', (['"""schmetterling.build.maven.exists"""'], {'side_effect': '[False, True]'}), False, 'from unittest.mock import call, MagicMock, patch\n'), (193, 'unittest.mock.MagicMock', 'MagicMock', ([], {'path': '"""pom_repo"""', 'return_value': '"""pom_repo"""'}), False, 'from unittest.mock import call, MagicMock, patch\n'), (203, 'schmetterling.build.maven.get_multi_modules', 'get_multi_modules', (['[(False, {})]', '"""build_dir"""'], {}), False, 'from schmetterling.build.maven import get_multi_modules\n'), (209, 'schmetterling.build.maven.get_multi_modules', 'get_multi_modules', (['[(True, {})]', '"""build_dir"""'], {}), False, 'from schmetterling.build.maven import get_multi_modules\n'), (219, 'schmetterling.build.maven.get_multi_modules', 'get_multi_modules', (["[(True, {'packaging': 'jar'})]", '"""build_dir"""'], {}), False, 'from schmetterling.build.maven import get_multi_modules\n'), (235, 'schmetterling.build.maven.get_multi_modules', 'get_multi_modules', (["[(True, {'artifact_id': 'super-pom', 'packaging': 'pom'})]", '"""build_dir"""'], {}), False, 'from schmetterling.build.maven import get_multi_modules\n'), (250, 'schmetterling.build.maven.get_multi_modules', 'get_multi_modules', (["[(True, {'artifact_id': 'pom', 'packaging': 'pom'})]", '"""build_dir"""'], {}), False, 'from schmetterling.build.maven import get_multi_modules\n'), (265, 'schmetterling.build.maven.get_multi_modules', 'get_multi_modules', (["[(True, {'artifact_id': 'x', 'packaging': 'x'})]", '"""build_dir"""'], {}), False, 'from schmetterling.build.maven import get_multi_modules\n'), (280, 'schmetterling.build.maven.get_multi_modules', 'get_multi_modules', (["[(True, {'artifact_id': 'war', 'packaging': 'war'})]", '"""build_dir"""'], {}), False, 'from schmetterling.build.maven import get_multi_modules\n'), (314, 'schmetterling.build.maven.get_multi_modules', 'get_multi_modules', (["[(True, {'artifact_id': 'jar1', 'packaging': 'jar'}), (True, {'artifact_id':\n    'jar2'}), (False, {'artifact_id': 'jar3'}), (True, {'artifact_id':\n    'war', 'packaging': 'war'})]", '"""build_dir"""'], {}), False, 'from schmetterling.build.maven import get_multi_modules\n'), (41, 'unittest.mock.call', 'call', (['"""updated1"""', '"""pom_dir1/mvn.log"""', '"""repository_dir"""', '"""settings_file"""', '"""logback_file"""'], {}), False, 'from unittest.mock import call, MagicMock, patch\n'), (42, 'unittest.mock.call', 'call', (['"""updated2"""', '"""pom_dir2/mvn.log"""', '"""repository_dir"""', '"""settings_file"""', '"""logback_file"""'], {}), False, 'from unittest.mock import call, MagicMock, patch\n'), (45, 'unittest.mock.call', 'call', (['"""create_command"""'], {'cwd': '"""pom_dir1"""'}), False, 'from unittest.mock import call, MagicMock, patch\n'), (46, 'unittest.mock.call', 'call', (['"""create_command"""'], {'cwd': '"""pom_dir2"""'}), False, 'from unittest.mock import call, MagicMock, patch\n'), (49, 'unittest.mock.call', 'call', (['"""coordinates1"""', '"""updated1"""', '"""pom_dir1/mvn.log"""'], {}), False, 'from unittest.mock import call, MagicMock, patch\n'), (50, 'unittest.mock.call', 'call', (['"""coordinates2"""', '"""updated2"""', '"""pom_dir2/mvn.log"""'], {}), False, 'from unittest.mock import call, MagicMock, patch\n'), (135, 'unittest.mock.MagicMock', 'MagicMock', ([], {'return_value': 'f'}), False, 'from unittest.mock import call, MagicMock, patch\n'), (147, 'unittest.mock.call', 'call', (['"""pd1"""'], {'exist_ok': '(True)'}), False, 'from unittest.mock import call, MagicMock, patch\n'), (148, 'unittest.mock.call', 'call', (['"""pd2"""'], {'exist_ok': '(True)'}), False, 'from unittest.mock import call, MagicMock, patch\n'), (149, 'unittest.mock.call.write', 'call.write', (['"""pc1"""'], {}), False, 'from unittest.mock import call, MagicMock, patch\n'), (149, 'unittest.mock.call.write', 'call.write', (['"""pc2"""'], {}), False, 'from unittest.mock import call, MagicMock, patch\n'), (198, 'schmetterling.build.maven.get_maven_repos', 'get_maven_repos', (['state'], {}), False, 'from schmetterling.build.maven import get_maven_repos\n'), (195, 'unittest.mock.MagicMock', 'MagicMock', ([], {'path': '"""non_pom_repo"""'}), False, 'from unittest.mock import call, MagicMock, patch\n')]