from view_common import *

class DashboardSliceInteractions(View):
    def get(self, request, name="users", **kwargs):
        colors = ["#005586", "#6ebe49", "orange", "#707170", "#00c4b3", "#077767", "dodgerblue", "#a79b94", "#c4e76a", "red"]

        groups = []
        matrix = []
        slices = list(Slice.objects.all())

        ids_by_slice = self.build_id_list(slices, name)

        slices = [x for x in slices if (len(ids_by_slice[x])>0)]

        for i,slice in enumerate(slices):
            groups.append({"name": slice.name, "color": colors[i%len(colors)]})
            row=self.buildMatrix(slice, slices, name, ids_by_slice)
            matrix.append(row)

        result = {"groups": groups, "matrix": matrix}

        if name=="users":
            result["title"] = "Slice interactions by user privilege"
            result["objectName"] = "users"
        elif name=="networks":
            result["title"] = "Slice interactions by network membership"
            result["objectName"] = "networks"
        elif name=="sites":
            result["title"] = "Slice interactions by site ownership"
            result["objectName"] = "sites"
        elif name=="sliver_sites":
            result["title"] = "Slice interactions by sliver sites"
            result["objectName"] = "sites"
        elif name=="sliver_nodes":
            result["title"] = "Slice interactions by sliver nodes"
            result["objectName"] = "nodes"

        return HttpResponse(json.dumps(result), mimetype='application/javascript')

    def build_id_list(self, slices, name):
        ids_by_slice = {}
        for slice in slices:
            # build up a list of object ids that are used by each slice
            ids_by_slice[slice] = self.getIds(slice, name)

        return ids_by_slice

    def buildMatrix(self, slice, slices, name, ids_by_slice):
        not_only_my_ids = []

        # build up a list of object ids that are used by other slices
        for otherSlice in ids_by_slice.keys():
            if (slice != otherSlice):
                for id in ids_by_slice[otherSlice]:
                    if not id in not_only_my_ids:
                        not_only_my_ids.append(id)

        # build up a list of ids that are used only by the slice, and not
        # shared with any other slice
        only_my_ids = []
        for id in ids_by_slice[slice]:
             if id not in not_only_my_ids:
                  only_my_ids.append(id)

        row = []
        for otherSlice in ids_by_slice.keys():
            if (otherSlice == slice):
                row.append(len(only_my_ids))
            else:
                row.append(self.inCommonIds(ids_by_slice[slice], ids_by_slice[otherSlice]))

        return row

    def getIds(self, slice, name):
        ids=[]
        if name=="users":
            for sp in slice.slice_privileges.all():
                    if sp.user.id not in ids:
                        ids.append(sp.user.id)
        elif name=="networks":
            for sp in slice.networkslice_set.all():
                    if sp.network.id not in ids:
                        ids.append(sp.network.id)
        elif name=="sites":
            ids = [slice.site.id]
        elif name=="sliver_sites":
            for sp in slice.slivers.all():
                 if sp.node.site.id not in ids:
                     ids.append(sp.node.site.id)
        elif name=="sliver_nodes":
            for sp in slice.slivers.all():
                 if sp.node.id not in ids:
                     ids.append(sp.node.id)
        return ids

    def inCommonIds(self, ids1, ids2):
        count = 0
        for id in ids1:
            if id in ids2:
                count+=1
        return count


