import os
import unittest
import six.moves.urllib.parse as urllibparse

from datarobot.helpers.eligibility_result import EligibilityResult
from datarobot.helpers.partitioning_methods import (BasePartitioningMethod, GroupTVH,
                                                    DatetimePartitioningSpecification)

_here = os.path.dirname(os.path.abspath(__file__))
FIXTURES_DIR = os.path.join(_here, 'fixtures')


def fixture_file_path(filename):
    return os.path.join(FIXTURES_DIR, filename)


class URLParamsTestCase(unittest.TestCase):

    def assert_has_params(self, url, **params):
        query_string = urllibparse.unquote(url).split('?')[1]
        query_parts = query_string.split('&')
        query_pairs = [param.split('=') for param in query_parts]
        query_params = {pair[0]: pair[1]
                        for pair in query_pairs}

        for key, value in query_params.items():
            self.assertIn(key, query_params,
                          'Expected parameter {} not found'.format(key))
            self.assertEqual(query_params[key], params[key])


class HelpersTestCase(unittest.TestCase):

    def test_cant_create_without_cv(self):
        with self.assertRaises(TypeError):
            BasePartitioningMethod(validation_type='CV')

        with self.assertRaises(TypeError):
            BasePartitioningMethod(cv_method='user')

    def test_partitioning_repr(self):
        p_method = GroupTVH(holdout_pct=1, validation_pct=2,
                            partition_key_cols=['one_feature', 'sec feature'],
                            seed=42)
        assert repr(p_method).startswith('GroupTVH({')

    def test_create_with_right(self):
        p_method = BasePartitioningMethod(validation_type='CV',
                                          cv_method='user')
        self.assertEqual(p_method.validation_type, 'CV')
        self.assertEqual(p_method.cv_method, 'user')

    def test_collect_payload(self):
        p_method = BasePartitioningMethod(validation_type='CV',
                                          cv_method='user')
        p = p_method.collect_payload()
        self.assertTrue('validation_type' in p)
        self.assertTrue('cv_method' in p)
        self.assertTrue('partition_key_cols' in p)
        self.assertEqual(p['validation_type'], 'CV')
        self.assertIsNone(p['partition_key_cols'])

    def test_datetime_collect_payload_unsupervised_mode(self):
        # if unsupervised_mode is not set or False we don't want it in payload
        spec = DatetimePartitioningSpecification('date', unsupervised_mode=False)
        payload = spec.collect_payload()
        assert 'unsupervised_mode' not in payload

        # otherwise it should be present
        spec = DatetimePartitioningSpecification('date', unsupervised_mode=True)
        payload = spec.collect_payload()
        assert payload['unsupervised_mode'] is True


def test_eligiblity_result_repr():
    er = EligibilityResult(False)
    representation = str(er)
    assert 'supported=False' in representation
    assert 'reason=\'\'' in representation
    assert 'context=\'\'' in representation

    er = EligibilityResult(True, reason='reason', context='context')
    representation = str(er)
    assert 'supported=True' in representation
    assert 'reason=\'reason\'' in representation
    assert 'context=\'context\'' in representation


def test_eligibility_result_with_japanese(unicode_string):
    er = EligibilityResult(True, reason=unicode_string, context=unicode_string)
    print(er)  # test __repr__
