import unittest
import numpy as np
from ..spintW import ODW, netW, mat2L, vecW
from ..util import lat2W

class TestODWeights(unittest.TestCase):
    def setUp(self):
        self.O = lat2W(2,2)
        self.D = lat2W(2,2)
        self.ODW =  np.array(
                [[ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.25,  0.25,  0.  ,  0.  ,
                0.25,  0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],
                [ 0.  ,  0.  ,  0.  ,  0.  ,  0.25,  0.  ,  0.  ,  0.25,  0.25,
                0.  ,  0.  ,  0.25,  0.  ,  0.  ,  0.  ,  0.  ],
                [ 0.  ,  0.  ,  0.  ,  0.  ,  0.25,  0.  ,  0.  ,  0.25,  0.25,
                0.  ,  0.  ,  0.25,  0.  ,  0.  ,  0.  ,  0.  ],
                [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.25,  0.25,  0.  ,  0.  ,
                0.25,  0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],
                [ 0.  ,  0.25,  0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,
                0.  ,  0.  ,  0.  ,  0.  ,  0.25,  0.25,  0.  ],
                [0.25,  0.  ,  0.  ,  0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,
                0.  ,  0.  ,  0.  ,  0.25,  0.  ,  0.  ,  0.25],
                [ 0.25,  0.  ,  0.  ,  0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,
                0.  ,  0.  ,  0.  ,  0.25,  0.  ,  0.  ,  0.25],
                [ 0.  ,  0.25,  0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,
                0.  ,  0.  ,  0.  ,  0.  ,  0.25,  0.25,  0.  ],
                [ 0.  ,  0.25,  0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,
                0.  ,  0.  ,  0.  ,  0.  ,  0.25,  0.25,  0.  ],
                [ 0.25,  0.  ,  0.  ,  0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,
                0.  ,  0.  ,  0.  ,  0.25,  0.  ,  0.  ,  0.25],
                [ 0.25,  0.  ,  0.  ,  0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,
                0.  ,  0.  ,  0.  ,  0.25,  0.  ,  0.  ,  0.25],
                [ 0.  ,  0.25,  0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,
                0.  ,  0.  ,  0.  ,  0.  ,  0.25,  0.25,  0.  ],
                [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.25,  0.25,  0.  ,  0.  ,
                0.25,  0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ],
                [ 0.  ,  0.  ,  0.  ,  0.  ,  0.25,  0.  ,  0.  ,  0.25,  0.25,
                0.  ,  0.  ,  0.25,  0.  ,  0.  ,  0.  ,  0.  ],
                [ 0.  ,  0.  ,  0.  ,  0.  ,  0.25,  0.  ,  0.  ,  0.25,  0.25,
                0.  ,  0.  ,  0.25,  0.  ,  0.  ,  0.  ,  0.  ],
                [ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.25,  0.25,  0.  ,  0.  ,
                0.25,  0.25,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ]])

    def test_ODW_full(self):
        W = ODW(self.O, self.D)
        np.testing.assert_allclose(self.ODW, W.full()[0])

class TestNetW(unittest.TestCase):
    def setUp(self):
        self.link_list = [('a', 'b'), ('a', 'c'), ('a', 'd'), 
                          ('b', 'a'), ('b', 'c'), ('b', 'd'), 
                          ('c', 'a'), ('c', 'b'), ('c', 'd'), 
                          ('d', 'a'), ('d', 'b'), ('d', 'c')]
        
        self._all = np.array([
            [ 0.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  0.,  1.,  1.,  0.],
            [ 1.,  0.,  1.,  1.,  1.,  0.,  1.,  1.,  1.,  1.,  0.,  1.],
            [ 1.,  1.,  0.,  1.,  0.,  1.,  1.,  0.,  1.,  1.,  1.,  1.],
            [ 1.,  1.,  1.,  0.,  1.,  1.,  1.,  1.,  0.,  1.,  1.,  0.],
            [ 1.,  1.,  0.,  1.,  0.,  1.,  1.,  1.,  1.,  0.,  1.,  1.],
            [ 1.,  0.,  1.,  1.,  1.,  0.,  0.,  1.,  1.,  1.,  1.,  1.],
            [ 1.,  1.,  1.,  1.,  1.,  0.,  0.,  1.,  1.,  1.,  0.,  1.],
            [ 1.,  1.,  0.,  1.,  1.,  1.,  1.,  0.,  1.,  0.,  1.,  1.],
            [ 0.,  1.,  1.,  0.,  1.,  1.,  1.,  1.,  0.,  1.,  1.,  1.],
            [ 1.,  1.,  1.,  1.,  0.,  1.,  1.,  0.,  1.,  0.,  1.,  1.],
            [ 1.,  0.,  1.,  1.,  1.,  1.,  0.,  1.,  1.,  1.,  0.,  1.],
            [ 0.,  1.,  1.,  0.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  0.]])


        self.O = np.array([
            [ 0.,  1.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
            [ 1.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
            [ 1.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.,  1.,  1.,  0.,  0.,  0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  1.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  1.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,  1.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.],
            [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,  1.],
            [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  0.]])

        
        self.D = np.array([
            [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  1.,  0.],
            [ 0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  1.],
            [ 0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  1.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  1.,  0.,  0.],
            [ 0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.],
            [ 0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.],
            [ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.],
            [ 0.,  0.,  1.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  1.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.],
            [ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.],
            [ 0.,  1.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]])


        self.OD = np.array([
            [ 0.,  1.,  1.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  1.,  0.],
            [ 1.,  0.,  1.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  1.],
            [ 1.,  1.,  0.,  0.,  0.,  1.,  0.,  0.,  1.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.,  1.,  1.,  1.,  0.,  0.,  1.,  0.,  0.],
            [ 0.,  1.,  0.,  1.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  1.],
            [ 0.,  0.,  1.,  1.,  1.,  0.,  0.,  0.,  1.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  1.,  0.,  0.,  0.,  1.,  1.,  1.,  0.,  0.],
            [ 1.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,  1.,  0.,  1.,  0.],
            [ 0.,  0.,  1.,  0.,  0.,  1.,  1.,  1.,  0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  1.,  0.,  0.,  1.,  0.,  0.,  0.,  1.,  1.],
            [ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,  1.,  0.,  1.],
            [ 0.,  1.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  1.,  1.,  0.]])


        self.C = np.array([
            [ 0.,  0.,  0.,  1.,  1.,  1.,  0.,  0.,  0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  1.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  1.],
            [ 1.,  1.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  1.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  1.],
            [ 1.,  1.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  1.,  1.,  1.,  0.,  0.,  0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  1.],
            [ 1.,  1.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  1.,  1.,  1.,  0.,  0.,  0.,  0.,  0.,  0.],
            [ 0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  1.,  0.,  0.,  0.]])

        self.edge_list = [(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)]

    def test_netOD(self):
        netW_OD = netW(self.link_list, share='OD')
        np.testing.assert_allclose(netW_OD.full()[0], self.OD)
        

    def test_netO(self):
        netW_O = netW(self.link_list, share='O')
        np.testing.assert_allclose(netW_O.full()[0], self.O)

    def test_netD(self):
        netW_D = netW(self.link_list, share='D')
        np.testing.assert_allclose(netW_D.full()[0], self.D)

    def test_netC(self):
        netW_C = netW(self.link_list, share='C')
        np.testing.assert_allclose(netW_C.full()[0], self.C)

    def test_net_all(self):
        netW_all = netW(self.link_list, share='A')
        np.testing.assert_allclose(netW_all.full()[0], self._all)

    def test_mat2L(self):
        mat = np.array([[0,1,1],[1,0,1],[1,1,0]])
        edge_list = mat2L(mat)
        self.assertEqual(edge_list, self.edge_list)

class TestVecW(unittest.TestCase):
    def setUp(self):
        self.origin_x = np.array([2,6,9,2])
        self.origin_y = np.array([4,8,2,5])
        self.dest_x = np.array([9,1,6,3])
        self.dest_y = np.array([3,6,2,7])
        self.continuous = np.array([
            [ 0.        ,  0.09759001,  0.12598816,  0.13736056],
            [ 0.09759001,  0.        ,  0.10783277,  0.18257419],
            [ 0.12598816,  0.10783277,  0.        ,  0.10425721],
            [ 0.13736056,  0.18257419,  0.10425721,  0.        ]])

    def test_vecW(self):
        W = vecW(self.origin_x, self.origin_y, self.dest_x, self.dest_y, 
                threshold=np.inf, binary=False)
        np.testing.assert_allclose(self.continuous, W.full()[0])
        
