import glob
import os
import subprocess
from os.path import dirname, realpath

import sys
import tarfile
import tempfile
import unittest


class InstallationTest(unittest.TestCase):

    def test_hacky_installation(self):
        """
        Hacky Installation Test

        BIG WARNING: If you are looking at this and considering using this method of "installing" ldclient, please do not.
         This is a highly unrecommended way of installing ldclient - it is only supported for legacy reasons, and will
         likely eventually be unsupported. Some features of ldclient may not work as intended if installed in this way.
        """

        tmp_dir = tempfile.mkdtemp()
        setup_script_path = os.path.join(dirname(dirname(realpath(__file__))), 'setup.py')
        # Create the ldclient tar ball
        subprocess.call(['python', setup_script_path, 'sdist', '--dist-dir=' + tmp_dir])

        matched_files = glob.glob(os.path.join(tmp_dir, 'ldclient*.tar.gz'))
        self.assertEqual(len(matched_files), 1, matched_files)
        tar_filename = matched_files[0]

        filename = os.path.join(tmp_dir, tar_filename)
        glob_path = 'ldclient-*'

        # Un-tar the tar file into the cwd
        tar = tarfile.open(filename)
        tar.extractall(path=tmp_dir)
        tar.close()

        # Construct the path to un-compressed file
        path = os.path.join(tmp_dir, glob_path)
        possible_paths = glob.glob(path)

        sys.path.insert(0, possible_paths[0])

        from ldclient import LDClient  # noqa: F401

        # test that a deprecated function still works
        from ldclient.decorators import deprecated
        from ldclient.client import versionchanged, versionadded, _enforce_string_ids

        class TestExtendedLDClient(LDClient):

            def __init__(self):
                self.compatibility_mode = (8, 10)
                self.ignore_deprecation_failure_for_version = False
                self.disable_string_identifier_conversion = False

            @deprecated(version='8.11', reason='some reason')
            def test_deprecated_function(self):
                return 1

            @versionchanged(version='8.11', reason='some reason')
            def test_version_changed_function(self):
                return 2

            @_enforce_string_ids('id')
            @versionadded('9.0')
            def test_commutativity_of_decorator1(self, id):
                return 3

            @versionadded('9.0')
            @_enforce_string_ids('id')
            def test_commutativity_of_decorator2(self, id):
                return 4

        client = TestExtendedLDClient()

        output1 = client.test_version_changed_function()
        self.assertEqual(output1, 2)

        output2 = client.test_deprecated_function()
        self.assertEqual(output2, 1)

        output3 = client.test_commutativity_of_decorator1("abc")
        self.assertEqual(output3, 3)

        output4 = client.test_commutativity_of_decorator2("abc")
        self.assertEqual(output4, 4)
