# coding=utf-8

import os
from unittest import TestCase, mock, main

import yaml

from pungi.scripts.create_extra_repo import CreateExtraRepo, ExtraVariantInfo, RepoInfo

FOLDER_WITH_TEST_DATA = os.path.join(
    os.path.dirname(
        os.path.abspath(__file__)
    ),
    'data/test_create_extra_repo/',
)

TEST_MODULE_INFO = yaml.load("""
---
document: modulemd
version: 2
data:
  name: perl-App-cpanminus
  stream: 1.7044
  version: 8030020210126085450
  context: 3a33b840
  arch: x86_64
  summary: Get, unpack, build and install CPAN modules
  description: >
    This is a CPAN client that requires zero configuration, and stands alone but it's
    maintainable and extensible with plug-ins and friendly to shell scripting.
  license:
    module:
    - MIT
    content:
    - (GPL+ or Artistic) and GPLv2+
    - ASL 2.0
    - GPL+ or Artistic
  dependencies:
  - buildrequires:
      perl: [5.30]
      platform: [el8.3.0]
    requires:
      perl: [5.30]
      perl-YAML: []
      platform: [el8]
  references:
    community: https://metacpan.org/release/App-cpanminus
  profiles:
    common:
      description: App-cpanminus distribution
      rpms:
      - perl-App-cpanminus
  api:
    rpms:
    - perl-App-cpanminus
  filter:
    rpms:
    - perl-CPAN-DistnameInfo-dummy
    - perl-Test-Deep
  buildopts:
    rpms:
      macros: >
        %_without_perl_CPAN_Meta_Check_enables_extra_test 1
  components:
    rpms:
      perl-App-cpanminus:
        rationale: The API.
        ref: perl-App-cpanminus-1.7044-5.module+el8.2.0+4278+abcfa81a.src.rpm
        buildorder: 1
        arches: [i686, x86_64]
      perl-CPAN-DistnameInfo:
        rationale: Run-time dependency.
        ref: stream-0.12-rhel-8.3.0
        arches: [i686, x86_64]
      perl-CPAN-Meta-Check:
        rationale: Run-time dependency.
        ref: perl-CPAN-Meta-Check-0.014-6.module+el8.2.0+4278+abcfa81a.src.rpm
        buildorder: 1
        arches: [i686, x86_64]
      perl-File-pushd:
        rationale: Run-time dependency.
        ref: perl-File-pushd-1.014-6.module+el8.2.0+4278+abcfa81a.src.rpm
        arches: [i686, x86_64]
      perl-Module-CPANfile:
        rationale: Run-time dependency.
        ref: perl-Module-CPANfile-1.1002-7.module+el8.2.0+4278+abcfa81a.src.rpm
        arches: [i686, x86_64]
      perl-Parse-PMFile:
        rationale: Run-time dependency.
        ref: perl-Parse-PMFile-0.41-7.module+el8.2.0+4278+abcfa81a.src.rpm
        arches: [i686, x86_64]
      perl-String-ShellQuote:
        rationale: Run-time dependency.
        ref: perl-String-ShellQuote-1.04-24.module+el8.2.0+4278+abcfa81a.src.rpm
        arches: [i686, x86_64]
      perl-Test-Deep:
        rationale: Build-time dependency.
        ref: stream-1.127-rhel-8.3.0
        arches: [i686, x86_64]
  artifacts:
    rpms:
    - perl-App-cpanminus-0:1.7044-5.module_el8.3.0+2027+c8990d1d.noarch
    - perl-App-cpanminus-0:1.7044-5.module_el8.3.0+2027+c8990d1d.src
    - perl-CPAN-Meta-Check-0:0.014-6.module_el8.3.0+2027+c8990d1d.noarch
    - perl-CPAN-Meta-Check-0:0.014-6.module_el8.3.0+2027+c8990d1d.src
    - perl-File-pushd-0:1.014-6.module_el8.3.0+2027+c8990d1d.noarch
    - perl-File-pushd-0:1.014-6.module_el8.3.0+2027+c8990d1d.src
    - perl-Module-CPANfile-0:1.1002-7.module_el8.3.0+2027+c8990d1d.noarch
    - perl-Module-CPANfile-0:1.1002-7.module_el8.3.0+2027+c8990d1d.src
    - perl-Parse-PMFile-0:0.41-7.module_el8.3.0+2027+c8990d1d.noarch
    - perl-Parse-PMFile-0:0.41-7.module_el8.3.0+2027+c8990d1d.src
    - perl-String-ShellQuote-0:1.04-24.module_el8.3.0+2027+c8990d1d.noarch
    - perl-String-ShellQuote-0:1.04-24.module_el8.3.0+2027+c8990d1d.src
...
""", Loader=yaml.BaseLoader)

TEST_REPO_INFO = RepoInfo(
    path=FOLDER_WITH_TEST_DATA,
    folder='test_repo',
    is_remote=False,
)
TEST_VARIANT_INFO = ExtraVariantInfo(
    name='TestRepo',
    arch='x86_64',
    packages=[],
    modules=[],
    repos=[TEST_REPO_INFO]
)

BS_BUILD_INFO = {
    'build_platforms': [
        {
            'architectures': ['non_fake_arch', 'fake_arch'],
            'name': 'fake_platform'
        }
    ]
}


class TestCreteExtraRepo(TestCase):

    maxDiff = None

    def test_01_get_repo_info_from_bs_repo(self):
        auth_token = 'fake_auth_token'
        build_id = 'fake_build_id'
        arch = 'fake_arch'
        packages = ['fake_package1', 'fake_package2']
        modules = ['fake_module1', 'fake_module2']

        request_object = mock.Mock()
        request_object.raise_for_status = lambda: True
        request_object.json = lambda: BS_BUILD_INFO
        with mock.patch(
            'pungi.scripts.create_extra_repo.requests.get',
            return_value=request_object,
        ) as mock_request_get:
            repos_info = CreateExtraRepo.get_repo_info_from_bs_repo(
                auth_token=auth_token,
                build_id=build_id,
                arch=arch,
                packages=packages,
                modules=modules,
            )
            self.assertEqual(
                [
                    ExtraVariantInfo(
                        name=f'{build_id}-fake_platform-{arch}',
                        arch=arch,
                        packages=packages,
                        modules=modules,
                        repos=[
                            RepoInfo(
                                path='https://build.cloudlinux.com/'
                                     f'build_repos/{build_id}/fake_platform',
                                folder=arch,
                                is_remote=True,
                            )
                        ]
                    )
                ],
                repos_info,
            )
            mock_request_get.assert_called_once_with(
                url=f'https://build.cloudlinux.com/api/v1/builds/{build_id}',
                headers={
                    'Authorization': f'Bearer {auth_token}',
                }
            )

    def test_02_create_extra_repo(self):
        with mock.patch(
            'pungi.scripts.create_extra_repo.'
            'CreateExtraRepo._read_local_modules_yaml',
            return_value=[],
        ) as mock__read_local_modules_yaml, mock.patch(
            'pungi.scripts.create_extra_repo.'
            'CreateExtraRepo._download_rpm_to_local_repo',
        ) as mock__download_rpm_to_local_repo, mock.patch(
            'pungi.scripts.create_extra_repo.'
            'CreateExtraRepo._dump_local_modules_yaml'
        ) as mock__dump_local_modules_yaml, mock.patch(
            'pungi.scripts.create_extra_repo.'
            'CreateExtraRepo._create_local_extra_repo'
        ) as mock__create_local_extra_repo:
            cer = CreateExtraRepo(
                variants=[TEST_VARIANT_INFO],
                bs_auth_token='fake_auth_token',
                local_repository_path='/path/to/local/repo',
                clear_target_repo=False,
            )
            mock__read_local_modules_yaml.assert_called_once_with()
            cer.create_extra_repo()
            mock__download_rpm_to_local_repo.assert_called_once_with(
                package_location='perl-App-cpanminus-1.7044-5.'
                                 'module_el8.3.0+2027+c8990d1d.noarch.rpm',
                repo_info=TEST_REPO_INFO,
            )
            mock__dump_local_modules_yaml.assert_called_once_with()
            mock__create_local_extra_repo.assert_called_once_with()
            self.assertEqual(
                [TEST_MODULE_INFO],
                cer.local_modules_data,
            )


if __name__ == '__main__':
    main()