import logging

from ..base import common
from ..base.testcase import ShedTestCase

log = logging.getLogger(__name__)

repository_name = "filtering_0420"
repository_description = "Galaxy filtering tool for test 0420"
repository_long_description = "Long description of Galaxy filtering tool for test 0420"

first_changeset_hash = ""

"""
1. Add and populate a repository to the tool shed with change set revision 0 (assume owner is test).
2. Add valid change set revision 1.
3. Visit the following url and check for appropriate strings: <tool shed base url>/view/user1
4. Visit the following url and check for appropriate strings: <tool shed base url>/view/user1/filtering_0420 .
   The resulting page should contain change set revision 1
5. Visit the following url and check for appropriate strings: <tool shed base url>/view/user1/filtering_0420/<revision 0> .
   The resulting page should not contain change set revision 1, but should contain change set revision 0.
6. Visit the following url and check for appropriate strings: <tool shed base url>/view/user1/filtering_0420/<invalid revision>
7. Visit the following url and check for appropriate strings: <tool shed base url>/view/user1/<invalid repository name>
8. Visit the following url and check for appropriate strings: <tool shed base url>/view/<invalid owner>
"""


class TestRepositoryCitableURLs(ShedTestCase):
    """Test repository citable url features."""

    def test_0000_initiate_users(self):
        """Create necessary user accounts and login as an admin user.

        Create all the user accounts that are needed for this test script to run independently of other tests.
        Previously created accounts will not be re-created.
        """
        self.login(email=common.test_user_1_email, username=common.test_user_1_name)
        self.login(email=common.admin_email, username=common.admin_username, explicit_logout=True)

    def test_0005_create_repository(self):
        """Create and populate the filtering_0420 repository

        We are at step 1.
        Add and populate a repository to the tool shed with change set revision 0 (assume owner is test_user_1).
        """
        global first_changeset_hash
        category = self.create_category(
            name="Test 0400 Repository Citable URLs", description="Test 0400 Repository Citable URLs category"
        )
        self.login(email=common.test_user_1_email, username=common.test_user_1_name)
        strings_displayed = self.expect_repo_created_strings(repository_name)
        repository = self.get_or_create_repository(
            name=repository_name,
            description=repository_description,
            long_description=repository_long_description,
            owner=common.test_user_1_name,
            category=category,
            strings_displayed=strings_displayed,
        )
        self.commit_tar_to_repository(
            repository,
            "filtering/filtering_2.2.0.tar",
            commit_message="Uploaded filtering 2.2.0 tarball.",
        )
        # We'll be checking for this hash later, after uploading another file to the repository, making get_repository_tip() not usable.
        first_changeset_hash = self.get_repository_tip(repository)

    def test_0010_upload_new_file_to_repository(self):
        """Upload a readme file to the repository in order to create a second changeset revision.

        We are at step 2.
        Add valid change set revision 1.
        The repository should now contain two changeset revisions, 0:<revision hash> and 1:<revision hash>.
        """
        repository = self._get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
        self.add_file_to_repository(repository, "readme.txt")

    def test_0015_load_user_view_page(self):
        """Load the /view/<username> page amd check for strings.

        We are at step 3.
        Visit the following url and check for appropriate strings: <tool shed base url>/view/user1
        """
        test_user_1 = self.test_db_util.get_user(common.test_user_1_email)
        encoded_user_id = self.security.encode_id(test_user_1.id)
        strings_displayed: list[str] = []
        strings_displayed_in_iframe = ["user1", "filtering_0420", repository_description]
        self.load_citable_url(
            username="user1",
            repository_name=None,
            changeset_revision=None,
            encoded_user_id=encoded_user_id,
            encoded_repository_id=None,
            strings_displayed=strings_displayed,
            strings_displayed_in_iframe=strings_displayed_in_iframe,
        )

    def test_0020_load_repository_view_page(self):
        """Load the /view/<user>/<repository> page and check for the appropriate strings.

        We are at step 4.
        Visit the following url and check for strings: ``<tool shed base url>/view/user1/filtering_0420`` .
        The resulting page should contain change set revision 1
        """
        repository = self._get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
        test_user_1 = self.test_db_util.get_user(common.test_user_1_email)
        encoded_user_id = self.security.encode_id(test_user_1.id)
        encoded_repository_id = repository.id
        strings_displayed: list[str] = []
        strings_displayed_in_iframe = [
            "user1",
            "filtering_0420",
            repository_long_description,
        ]
        strings_displayed_in_iframe.append(self.get_repository_tip(repository))
        self.load_citable_url(
            username="user1",
            repository_name="filtering_0420",
            changeset_revision=None,
            encoded_user_id=encoded_user_id,
            encoded_repository_id=encoded_repository_id,
            strings_displayed=strings_displayed,
            strings_displayed_in_iframe=strings_displayed_in_iframe,
        )

    def test_0025_load_view_page_for_previous_revision(self):
        """Load a citable url for a past changeset revision and verify that strings display.

        We are at step 5.
        Visit the following url and check for appropriate strings: ``<tool shed base url>/view/user1/filtering_0420/<revision 0>`` .
        The resulting page should not contain change set revision 1, but should contain change set revision 0.
        """
        repository = self._get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
        test_user_1 = self.test_db_util.get_user(common.test_user_1_email)
        encoded_user_id = self.security.encode_id(test_user_1.id)
        encoded_repository_id = repository.id
        strings_displayed: list[str] = []
        strings_displayed_in_iframe = [
            "user1",
            "filtering_0420",
            repository_long_description,
            first_changeset_hash,
        ]
        self.load_citable_url(
            username="user1",
            repository_name="filtering_0420",
            changeset_revision=first_changeset_hash,
            encoded_user_id=encoded_user_id,
            encoded_repository_id=encoded_repository_id,
            strings_displayed=strings_displayed,
            strings_displayed_in_iframe=strings_displayed_in_iframe,
        )

    def test_0030_load_sharable_url_with_invalid_changeset_revision(self):
        """Load a citable url with an invalid changeset revision specified."""
        repository = self._get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
        test_user_1 = self.test_db_util.get_user(common.test_user_1_email)
        encoded_user_id = self.security.encode_id(test_user_1.id)
        encoded_repository_id = repository.id
        invalid_changeset_hash = "invalid"
        strings_displayed = ["The change log does not include revision " + invalid_changeset_hash]
        self.load_citable_url(
            username="user1",
            repository_name="filtering_0420",
            changeset_revision=invalid_changeset_hash,
            encoded_user_id=encoded_user_id,
            encoded_repository_id=encoded_repository_id,
            strings_displayed=strings_displayed,
        )

    def test_0035_load_sharable_url_with_invalid_repository_name(self):
        """Load a citable url with an invalid changeset revision specified.

        We are at step 7.
        Visit the following url and check for appropriate strings: <tool shed base url>/view/user1/!!invalid!!
        """
        test_user_1 = self.test_db_util.get_user(common.test_user_1_email)
        encoded_user_id = self.security.encode_id(test_user_1.id)
        strings_displayed = ["Repository user1/!!invalid!! is not found"]
        strings_displayed_in_iframe: list[str] = []
        self.load_citable_url(
            username="user1",
            repository_name="!!invalid!!",
            changeset_revision=None,
            encoded_user_id=encoded_user_id,
            encoded_repository_id=None,
            strings_displayed=strings_displayed,
            strings_displayed_in_iframe=strings_displayed_in_iframe,
        )

    def test_0040_load_sharable_url_with_invalid_owner(self):
        """Load a citable url with an invalid owner.

        We are at step 8.
        Visit the following url and check for appropriate strings: <tool shed base url>/view/!!invalid!!
        """
        strings_displayed = ["No repositories found"]
        self.load_citable_url(
            username="!!invalid!!",
            repository_name=None,
            changeset_revision=None,
            encoded_user_id=None,
            encoded_repository_id=None,
            strings_displayed=strings_displayed,
        )
