#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Test EHRcorral.

Tests for `ehrcorral` module.
"""

from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from __future__ import unicode_literals

import unittest
import json
import os

from ehrcorral.herd import Herd
from ehrcorral.herd import gen_record
from ehrcorral.herd import compress
from faker import Faker

fake = Faker()


class TestHerdProperties(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        data_path = os.path.join(os.path.dirname(__file__), 'profiles_100.json')
        with open(data_path, 'r') as data_file:
            population = tuple(json.load(data_file))
        records = [gen_record(profile) for profile in population]
        cls.herd = Herd()
        cls.herd.populate(records)

    def test_herd_str_method(self):
        try:
            herd = Herd()
            str(herd)
        except Exception as e:
            self.fail("Getting string of empty herd raised: {}.".format(e))
        self.assertEqual(str(herd), '()')
        try:
            herd = self.herd
            str(herd)
        except Exception as e:
            self.fail("Getting string of herd raised: {}.".format(e))
        self.assertNotEqual(str(herd), '()')

    def test_retrieving_populated_herd_size(self):
        self.assertEqual(self.herd.size, 100)

    def test_retrieving_herd_size_with_no_population(self):
        try:
            herd = Herd()
        except Exception as e:
            self.fail("Creating herd with no population raised: {}.".format(e))
        self.assertEqual(herd.size, 0)


class TestHerdCreation(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        data_path = os.path.join(os.path.dirname(__file__), 'profiles_100.json')
        with open(data_path, 'r') as data_file:
            cls.profiles = tuple(json.load(data_file))

    def test_population_loaded_correctly(self):
        self.assertEqual(len(self.profiles), 100)

    def test_populating_herd(self):
        records = [gen_record(profile) for profile in self.profiles]
        herd = Herd()
        herd.populate(records)
        self.assertEqual(herd.size, 100)


class TestRecordGeneration(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        data_path = os.path.join(os.path.dirname(__file__), 'profiles_100.json')
        with open(data_path, 'r') as data_file:
            cls.profiles = tuple(json.load(data_file))

    def test_record_generation_from_fake_profiles(self):
        records = [gen_record(profile) for profile in self.profiles]
        self.assertEqual(len(records), 100)

    def test_record_generation_catches_invalid_profiles(self):
        with self.assertRaises(ValueError):
            record = gen_record({'forename': 'Joe'})
        with self.assertRaises(ValueError):
            record = gen_record({'birth_surname': 'Smith'})
        with self.assertRaises(ValueError):
            record = gen_record({'test': 'test'})


class TestPhonemicCompression(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.name = ['Jellyfish']
        cls.names = ['Jellyfish', 'Exeter']

    def test_soundex_compression(self):
        single_compression = compress(self.name, 'soundex')
        self.assertEqual(single_compression, ['J412'])
        multiple_compressions = compress(self.names, 'soundex')
        self.assertEqual(multiple_compressions, ['J412', 'E236'])

    def test_nysiis_compression(self):
        single_compression = compress(self.name, 'nysiis')
        self.assertEqual(single_compression, ['JALYF'])
        multiple_compressions = compress(self.names, 'nysiis')
        self.assertEqual(multiple_compressions, ['JALYF', 'EXATAR'])

    def test_metaphone_compression(self):
        single_compression = compress(self.name, 'metaphone')
        self.assertEqual(single_compression, ['JLFX'])
        multiple_compressions = compress(self.names, 'metaphone')
        self.assertEqual(multiple_compressions, ['JLFX', 'EKSTR'])

    def test_dmetaphone_compression(self):
        single_compression = compress(self.name, 'dmetaphone')
        self.assertEqual(single_compression, ['JLFX', 'ALFX'])
        multiple_compressions = compress(self.names, 'dmetaphone')
        self.assertEqual(multiple_compressions, ['JLFX', 'ALFX', 'AKSTR'])


class TestPhonemicBlocking(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        # Female profile with different birth surname and current surname
        female = {
            'forename': 'Adelyn',
            'mid_forename': 'Heidenreich',
            'current_surname': 'Bartell',
            'birth_surname': 'Gerlach'
        }
        cls.female_record = gen_record(female)
        # Male profile with some missing name fields
        male = {
            'forename': 'Oliver',
            'current_surname': 'Nader'
        }
        cls.male_record = gen_record(male)

    def test_multiple_surnames_and_forenames(self):
        self.female_record.gen_blocks('dmetaphone')
        expected_blocks = ['PRTLA', 'KRLKA', 'JRLKA', 'PRTLH', 'KRLKH', 'JRLKH']
        self.assertItemsEqual(self.female_record._blocks, expected_blocks)

    def test_single_forename_and_surname(self):
        self.male_record.gen_blocks('dmetaphone')
        expected_blocks = ['NTRO']
        self.assertItemsEqual(self.male_record._blocks, expected_blocks)

@@ -2202,24 +2202,667 @@
 ize, 100)%0A%0A%0A
+class TestHerdExplode(unittest.TestCase):%0A%0A    @classmethod%0A    def setUpClass(cls):%0A        data_path = os.path.join(os.path.dirname(__file__), 'profiles_100.json')%0A        with open(data_path, 'r') as data_file:%0A            population = tuple(json.load(data_file))%0A        records = %5Bgen_record(profile) for profile in population%5D%0A        cls.herd = Herd()%0A        cls.herd.populate(records)%0A%0A    def test_herd_exploding(self):%0A        self.herd._explode(blocking='dmetaphone')%0A        for record in self.herd._population:%0A            self.assertIsInstance(record._blocks, tuple)%0A            self.assertTrue(1 %3C= len(record._blocks) %3C= 8)%0A%0A%0A
 class TestRe

Add test case for exploding a Herd