import unittest
import numpy as np

import unittest


from helper import fixture_file

from crankshaft.space_time_dynamics import Markov
import crankshaft.space_time_dynamics as std
from crankshaft import random_seeds
from crankshaft.analysis_data_provider import AnalysisDataProvider
import json


class FakeDataProvider(AnalysisDataProvider):
    def __init__(self, data):
        self.mock_result = data

    def get_markov(self, w_type, params):
        return self.mock_result


class SpaceTimeTests(unittest.TestCase):
    """Testing class for Markov Functions."""

    def setUp(self):
        self.params = {"id_col": "cartodb_id",
                       "time_cols": ['dec_2013', 'jan_2014', 'feb_2014'],
                       "subquery": "SELECT * FROM a_list",
                       "geom_col": "the_geom",
                       "num_ngbrs": 321}
        self.neighbors_data = json.loads(
          open(fixture_file('neighbors_markov.json')).read())
        self.markov_data = json.loads(open(fixture_file('markov.json')).read())

        self.time_data = np.array([i * np.ones(10, dtype=float)
                                   for i in range(10)]).T

        self.transition_matrix = np.array([
                [[0.96341463, 0.0304878, 0.00609756, 0., 0.],
                 [0.06040268, 0.83221477, 0.10738255, 0., 0.],
                 [0., 0.14, 0.74, 0.12, 0.],
                 [0., 0.03571429, 0.32142857, 0.57142857, 0.07142857],
                 [0., 0., 0., 0.16666667, 0.83333333]],
                [[0.79831933, 0.16806723, 0.03361345, 0., 0.],
                 [0.0754717, 0.88207547, 0.04245283, 0., 0.],
                 [0.00537634, 0.06989247, 0.8655914, 0.05913978, 0.],
                 [0., 0., 0.06372549, 0.90196078, 0.03431373],
                 [0., 0., 0., 0.19444444, 0.80555556]],
                [[0.84693878, 0.15306122, 0., 0., 0.],
                 [0.08133971, 0.78947368, 0.1291866, 0., 0.],
                 [0.00518135, 0.0984456, 0.79274611, 0.0984456, 0.00518135],
                 [0., 0., 0.09411765, 0.87058824, 0.03529412],
                 [0., 0., 0., 0.10204082, 0.89795918]],
                [[0.8852459, 0.09836066, 0., 0.01639344, 0.],
                 [0.03875969, 0.81395349, 0.13953488, 0., 0.00775194],
                 [0.0049505, 0.09405941, 0.77722772, 0.11881188, 0.0049505],
                 [0., 0.02339181, 0.12865497, 0.75438596, 0.09356725],
                 [0., 0., 0., 0.09661836, 0.90338164]],
                [[0.33333333, 0.66666667, 0., 0., 0.],
                 [0.0483871, 0.77419355, 0.16129032, 0.01612903, 0.],
                 [0.01149425, 0.16091954, 0.74712644, 0.08045977, 0.],
                 [0., 0.01036269, 0.06217617, 0.89637306, 0.03108808],
                 [0., 0., 0., 0.02352941, 0.97647059]]]
                 )

    def test_spatial_markov(self):
        """Test Spatial Markov."""
        data = [{'id': d['id'],
                 'attr1': d['y1995'],
                 'attr2': d['y1996'],
                 'attr3': d['y1997'],
                 'attr4': d['y1998'],
                 'attr5': d['y1999'],
                 'attr6': d['y2000'],
                 'attr7': d['y2001'],
                 'attr8': d['y2002'],
                 'attr9': d['y2003'],
                 'attr10': d['y2004'],
                 'attr11': d['y2005'],
                 'attr12': d['y2006'],
                 'attr13': d['y2007'],
                 'attr14': d['y2008'],
                 'attr15': d['y2009'],
                 'neighbors': d['neighbors']} for d in self.neighbors_data]
        # print(str(data[0]))
        markov = Markov(FakeDataProvider(data))
        random_seeds.set_random_seeds(1234)

        result = markov.spatial_trend('subquery',
                                      ['y1995', 'y1996', 'y1997', 'y1998',
                                       'y1999', 'y2000', 'y2001', 'y2002',
                                       'y2003', 'y2004', 'y2005', 'y2006',
                                       'y2007', 'y2008', 'y2009'],
                                      5, 'knn', 5, 0, 'the_geom',
                                      'cartodb_id')

        self.assertTrue(result is not None)
        result = [(row[0], row[1], row[2], row[3], row[4]) for row in result]
        print result[0]
        expected = self.markov_data
        for ([res_trend, res_up, res_down, res_vol, res_id],
             [exp_trend, exp_up, exp_down, exp_vol, exp_id]
             ) in zip(result, expected):
            self.assertAlmostEqual(res_trend, exp_trend)

    def test_get_time_data(self):
        """Test get_time_data"""
        data = [{'attr1': d['y1995'],
                 'attr2': d['y1996'],
                 'attr3': d['y1997'],
                 'attr4': d['y1998'],
                 'attr5': d['y1999'],
                 'attr6': d['y2000'],
                 'attr7': d['y2001'],
                 'attr8': d['y2002'],
                 'attr9': d['y2003'],
                 'attr10': d['y2004'],
                 'attr11': d['y2005'],
                 'attr12': d['y2006'],
                 'attr13': d['y2007'],
                 'attr14': d['y2008'],
                 'attr15': d['y2009']} for d in self.neighbors_data]

        result = std.get_time_data(data, ['y1995', 'y1996', 'y1997', 'y1998',
                                          'y1999', 'y2000', 'y2001', 'y2002',
                                          'y2003', 'y2004', 'y2005', 'y2006',
                                          'y2007', 'y2008', 'y2009'])

        # expected was prepared from PySAL example:
        # f = ps.open(ps.examples.get_path("usjoin.csv"))
        # pci = np.array([f.by_col[str(y)]
        #                 for y in range(1995, 2010)]).transpose()
        # rpci = pci / (pci.mean(axis = 0))

        expected = np.array(
          [[0.87654416, 0.863147, 0.85637567, 0.84811668, 0.8446154,
            0.83271652,  0.83786314, 0.85012593, 0.85509656, 0.86416612,
            0.87119375, 0.86302631,  0.86148267, 0.86252252, 0.86746356],
           [0.9188951,  0.91757931, 0.92333258, 0.92517289, 0.92552388,
            0.90746978,  0.89830489, 0.89431991, 0.88924794, 0.89815176,
            0.91832091, 0.91706054,  0.90139505, 0.87897455, 0.86216858],
           [0.82591007, 0.82548596, 0.81989793, 0.81503235, 0.81731522,
            0.78964559,  0.80584442, 0.8084998,  0.82258551, 0.82668196,
            0.82373724, 0.81814804,  0.83675961, 0.83574199, 0.84647177],
           [1.09088176, 1.08537689, 1.08456418, 1.08415404, 1.09898841,
            1.14506948,  1.12151133, 1.11160697, 1.10888621, 1.11399806,
            1.12168029, 1.13164797,  1.12958508, 1.11371818, 1.09936775],
           [1.10731446, 1.11373944, 1.13283638, 1.14472559, 1.15910025,
            1.16898201,  1.17212488, 1.14752303, 1.11843284, 1.11024964,
            1.11943471, 1.11736468,  1.10863242, 1.09642516, 1.07762337],
           [1.42269757, 1.42118434, 1.44273502, 1.43577571, 1.44400684,
            1.44184737,  1.44782832, 1.41978227, 1.39092208, 1.4059372,
            1.40788646, 1.44052766,  1.45241216, 1.43306098, 1.4174431],
           [1.13073885, 1.13110513, 1.11074708, 1.13364636, 1.13088149,
            1.10888138,  1.11856629, 1.13062931, 1.11944984, 1.12446239,
            1.11671008, 1.10880034,  1.08401709, 1.06959206, 1.07875225],
           [1.04706124, 1.04516831, 1.04253372, 1.03239987, 1.02072545,
            0.99854316,  0.9880258,  0.99669587, 0.99327676, 1.01400905,
            1.03176742, 1.040511,  1.01749645, 0.9936394,  0.98279746],
           [0.98996986, 1.00143564, 0.99491,  1.00188408, 1.00455845,
            0.99127006,  0.97925917, 0.9683482,  0.95335147, 0.93694787,
            0.94308213, 0.92232874,  0.91284091, 0.89689833, 0.88928858],
           [0.87418391, 0.86416601, 0.84425695, 0.8404494,  0.83903044,
            0.8578708,  0.86036185, 0.86107306, 0.8500772,  0.86981998,
            0.86837929, 0.87204141,  0.86633032, 0.84946077, 0.83287146],
           [1.14196118, 1.14660262, 1.14892712, 1.14909594, 1.14436624,
            1.14450183,  1.12349752, 1.12596664, 1.12213996, 1.1119989,
            1.10257792, 1.10491258,  1.11059842, 1.10509795, 1.10020097],
           [0.97282463, 0.96700147, 0.96252588, 0.9653878,  0.96057687,
            0.95831051,  0.94480909, 0.94804195, 0.95430286, 0.94103989,
            0.92122519, 0.91010201,  0.89280392, 0.89298243, 0.89165385],
           [0.94325468, 0.96436902, 0.96455242, 0.95243009, 0.94117647,
            0.9480927,  0.93539182, 0.95388718, 0.94597005, 0.96918424,
            0.94781281, 0.93466815,  0.94281559, 0.96520315, 0.96715441],
           [0.97478408, 0.98169225, 0.98712809, 0.98474769, 0.98559897,
            0.98687073,  0.99237486, 0.98209969, 0.9877653,  0.97399471,
            0.96910087, 0.98416665,  0.98423613, 0.99823861, 0.99545704],
           [0.85570269, 0.85575915, 0.85986132, 0.85693406, 0.8538012,
            0.86191535,  0.84981451, 0.85472102, 0.84564835, 0.83998883,
            0.83478547, 0.82803648,  0.8198736,  0.82265395, 0.8399404],
           [0.87022047, 0.85996258, 0.85961813, 0.85689572, 0.83947136,
            0.82785597,  0.86008789, 0.86776298, 0.86720209, 0.8676334,
            0.89179317, 0.94202108,  0.9422231,  0.93902708, 0.94479184],
           [0.90134907, 0.90407738, 0.90403991, 0.90201769, 0.90399238,
            0.90906632,  0.92693339, 0.93695966, 0.94242697, 0.94338265,
            0.91981796, 0.91108804,  0.90543476, 0.91737138, 0.94793657],
           [1.1977611,  1.18222564, 1.18439158, 1.18267865, 1.19286723,
            1.20172869,  1.21328691, 1.22624778, 1.22397075, 1.23857042,
            1.24419893, 1.23929384,  1.23418676, 1.23626739, 1.26754398],
           [1.24919678, 1.25754773, 1.26991161, 1.28020651, 1.30625667,
            1.34790023,  1.34399863, 1.32575181, 1.30795492, 1.30544841,
            1.30303302, 1.32107766,  1.32936244, 1.33001241, 1.33288462],
           [1.06768004, 1.03799276, 1.03637303, 1.02768449, 1.03296093,
            1.05059016,  1.03405057, 1.02747623, 1.03162734, 0.9961416,
            0.97356208, 0.94241549,  0.92754547, 0.92549227, 0.92138102],
           [1.09475614, 1.11526796, 1.11654299, 1.13103948, 1.13143264,
            1.13889622,  1.12442212, 1.13367018, 1.13982256, 1.14029944,
            1.11979401, 1.10905389,  1.10577769, 1.11166825, 1.09985155],
           [0.76530058, 0.76612841, 0.76542451, 0.76722683, 0.76014284,
            0.74480073,  0.76098396, 0.76156903, 0.76651952, 0.76533288,
            0.78205934, 0.76842416,  0.77487118, 0.77768683, 0.78801192],
           [0.98391336, 0.98075816, 0.98295341, 0.97386015, 0.96913803,
            0.97370819,  0.96419154, 0.97209861, 0.97441313, 0.96356162,
            0.94745352, 0.93965462,  0.93069645, 0.94020973, 0.94358232],
           [0.83561828, 0.82298088, 0.81738502, 0.81748588, 0.80904801,
            0.80071489,  0.83358256, 0.83451613, 0.85175032, 0.85954307,
            0.86790024, 0.87170334,  0.87863799, 0.87497981, 0.87888675],
           [0.98845573, 1.02092428, 0.99665283, 0.99141823, 0.99386619,
            0.98733195,  0.99644997, 0.99669587, 1.02559097, 1.01116651,
            0.99988024, 0.97906749,  0.99323123, 1.00204939, 0.99602148],
           [1.14930913, 1.15241949, 1.14300962, 1.14265542, 1.13984683,
            1.08312397,  1.05192626, 1.04230892, 1.05577278, 1.08569751,
            1.12443486, 1.08891079,  1.08603695, 1.05997314, 1.02160943],
           [1.11368269, 1.1057147,  1.11893431, 1.13778669, 1.1432272,
            1.18257029,  1.16226243, 1.16009196, 1.14467789, 1.14820235,
            1.12386598, 1.12680236,  1.12357937, 1.1159258,  1.12570828],
           [1.30379431, 1.30752186, 1.31206366, 1.31532267, 1.30625667,
            1.31210239,  1.29989156, 1.29203193, 1.27183516, 1.26830786,
            1.2617743,  1.28656675,  1.29734097, 1.29390205, 1.29345446],
           [0.83953719, 0.82701448, 0.82006005, 0.81188876, 0.80294864,
            0.78772975,  0.82848011, 0.8259679,  0.82435705, 0.83108634,
            0.84373784, 0.83891093,  0.84349247, 0.85637272, 0.86539395],
           [1.23450087, 1.2426022,  1.23537935, 1.23581293, 1.24522626,
            1.2256767,  1.21126648, 1.19377804, 1.18355337, 1.19674434,
            1.21536573, 1.23653297,  1.27962009, 1.27968392, 1.25907738],
           [0.9769662,  0.97400719, 0.98035944, 0.97581531, 0.95543282,
            0.96480308,  0.94686376, 0.93679073, 0.92540049, 0.92988835,
            0.93442917, 0.92100464,  0.91475304, 0.90249622, 0.9021363],
           [0.84986886, 0.8986851,  0.84295997, 0.87280534, 0.85659368,
            0.88937573,  0.894401, 0.90448993, 0.95495898, 0.92698333,
            0.94745352, 0.92562488,  0.96635366, 1.02520312, 1.0394296],
           [1.01922808, 1.00258203, 1.00974428, 1.00303417, 0.99765073,
            1.00759019,  0.99192968, 0.99747298, 0.99550759, 0.97583768,
            0.9610168,  0.94779638,  0.93759089, 0.93353431, 0.94121705],
           [0.86367411, 0.85558932, 0.85544346, 0.85103025, 0.84336613,
            0.83434854,  0.85813595, 0.84667961, 0.84374558, 0.85951183,
            0.87194227, 0.89455097,  0.88283929, 0.90349491, 0.90600675],
           [1.00947534, 1.00411055, 1.00698819, 0.99513687, 0.99291086,