# Path: rhizi/model/graph.py
# class Topo_Diff(object):
#     """
#     Represents a change to the graph topology
#     """
# 
#     class Commit_Result_Type(dict):
#         """
#         Topo_Diff graph commit result type
#         """
#         def __init__(self, node_id_set_add=[],
#                            link_id_set_add=[],
#                            node_id_set_rm=[],
#                            link_id_set_rm=[]):
#             self['node_id_set_add'] = node_id_set_add
#             self['link_id_set_add'] = link_id_set_add
#             self['node_id_set_rm'] = node_id_set_rm
#             self['link_id_set_rm'] = link_id_set_rm
#             self['meta'] = {}
# 
#         @staticmethod
#         def from_json_dict(json_dict):
#             ret = Topo_Diff.Commit_Result_Type()
#             ret.__dict__ = json_dict
#             return ret
# 
#     class JSON_Encoder(json.JSONEncoder):
#         """
#         Topo_Diff is not a plain dict, so we provide a json encoder
#         """
#         def default(self, obj):
#             return obj.to_json_dict()
# 
#     @staticmethod
#     def from_json_dict(json_dict):
#         """
#         construct from dict - no node/link constructor set must be provided
#         """
#         ret = Topo_Diff()
# 
#         # merge keys - this allows constructor argument omission (link_id_set_rm,
#         # node_id_set_rm, etc.) such as when constructing from POST JSON data
#         for k, _ in ret.__dict__.items():
#             v = json_dict.get(k)
#             if None != v:
#                 ret.__dict__[k] = v
#         return ret
# 
#     def __init__(self, link_id_set_rm=[],
#                        node_id_set_rm=[],
#                        node_set_add=[],
#                        link_set_add=[],
#                        meta={}):
# 
#         self.link_id_set_rm = link_id_set_rm
#         self.node_id_set_rm = node_id_set_rm
#         self.node_set_add = node_set_add
#         self.link_set_add = link_set_add
#         self.meta = {}
# 
#     def __str__(self):
#         return __name__ + ': ' + ', '.join('%s: %s' % (k, v) for k, v in self.__dict__.items())
# 
#     def len__n_add(self):
#         return len(self.node_set_add)
# 
#     def len__n_id_rm(self):
#         return len(self.node_id_set_rm)
# 
#     def len__l_add(self):
#         return len(self.link_set_add)
# 
#     def len__l_id_rm(self):
#         return len(self.link_id_set_rm)
# 
#     def is_empty(self):
#         return self.len__n_add() + self.len__n_id_rm() + self.len__l_add() + self.len__l_id_rm() == 0
# 
#     def to_json_dict(self):
#         ret = {k: getattr(self, k) for k in ['link_id_set_rm',
#                                              'node_id_set_rm',
#                                              'node_set_add',
#                                              'link_set_add',
#                                              'meta'] }
#         return ret
# 
#     def to_str__commit_name(self):
#         return 'TD: +n:%d l:%d -n:%d -l:%d' % (len(self.node_set_add),
#                                                len(self.link_set_add),
#                                                len(self.node_id_set_rm),
#                                                len(self.link_id_set_rm))
# 
#     def check_validity(self, topo_diff_dict):
#         """
#         Topo_Diff may represent invalid operations, eg. adding a link while
#          removing it's end-point - this stub should check for that
#         """
#         pass


import argparse  # TODO - use the newer / shorter argument parser. y?
import json
import os
import sys
import uuid
from collections import namedtuple
from ..model.graph import Topo_Diff
from ..rz_file import RZFile
from .. import rz

    Missing:
        this loses all the history.
        no user recorded for newly created doc
    """
    global kernel
    destination = kernel.rzdoc__create(rzdoc_name)
    ctx = namedtuple('Context', ['user_name', 'rzdoc'])(None, destination)
    kernel.diff_commit__topo(clone, ctx)


def names():
    global kernel
    return [v['name'] for v in kernel.rzdoc__list()]


def create_id():
    return uuid.uuid4().get_hex()[:8]


def merge_topos(topos, names):
    """
    Merge a number of Topo_Diff's

    result node set is union of nodes
    conflicting nodes:
        same name nodes take the first (id wise)
        attributes: take the first
    result link set is merged (well defined: replace dropped id by chosen id in all links)
    """

# Path: rhizi/model/graph.py
# class Topo_Diff(object):
#     """
#     Represents a change to the graph topology
#     """
# 
#     class Commit_Result_Type(dict):
#         """
#         Topo_Diff graph commit result type
#         """
#         def __init__(self, node_id_set_add=[],
#                            link_id_set_add=[],
#                            node_id_set_rm=[],
#                            link_id_set_rm=[]):
#             self['node_id_set_add'] = node_id_set_add
#             self['link_id_set_add'] = link_id_set_add
#             self['node_id_set_rm'] = node_id_set_rm
#             self['link_id_set_rm'] = link_id_set_rm
#             self['meta'] = {}
# 
#         @staticmethod
#         def from_json_dict(json_dict):
#             ret = Topo_Diff.Commit_Result_Type()
#             ret.__dict__ = json_dict
#             return ret
# 
#     class JSON_Encoder(json.JSONEncoder):
#         """
#         Topo_Diff is not a plain dict, so we provide a json encoder
#         """
#         def default(self, obj):
#             return obj.to_json_dict()
# 
#     @staticmethod
#     def from_json_dict(json_dict):
#         """
#         construct from dict - no node/link constructor set must be provided
#         """
#         ret = Topo_Diff()
# 
#         # merge keys - this allows constructor argument omission (link_id_set_rm,
#         # node_id_set_rm, etc.) such as when constructing from POST JSON data
#         for k, _ in ret.__dict__.items():
#             v = json_dict.get(k)
#             if None != v:
#                 ret.__dict__[k] = v
#         return ret
# 
#     def __init__(self, link_id_set_rm=[],
#                        node_id_set_rm=[],
#                        node_set_add=[],
#                        link_set_add=[],
#                        meta={}):
# 
#         self.link_id_set_rm = link_id_set_rm
#         self.node_id_set_rm = node_id_set_rm
#         self.node_set_add = node_set_add
#         self.link_set_add = link_set_add
#         self.meta = {}
# 
#     def __str__(self):
#         return __name__ + ': ' + ', '.join('%s: %s' % (k, v) for k, v in self.__dict__.items())
# 
#     def len__n_add(self):
#         return len(self.node_set_add)
# 
#     def len__n_id_rm(self):
#         return len(self.node_id_set_rm)
# 
#     def len__l_add(self):
#         return len(self.link_set_add)
# 
#     def len__l_id_rm(self):
#         return len(self.link_id_set_rm)
# 
#     def is_empty(self):
#         return self.len__n_add() + self.len__n_id_rm() + self.len__l_add() + self.len__l_id_rm() == 0
# 
#     def to_json_dict(self):
#         ret = {k: getattr(self, k) for k in ['link_id_set_rm',
#                                              'node_id_set_rm',
#                                              'node_set_add',
#                                              'link_set_add',
#                                              'meta'] }
#         return ret
# 
#     def to_str__commit_name(self):
#         return 'TD: +n:%d l:%d -n:%d -l:%d' % (len(self.node_set_add),
#                                                len(self.link_set_add),
#                                                len(self.node_id_set_rm),
#                                                len(self.link_id_set_rm))
# 
#     def check_validity(self, topo_diff_dict):
#         """
#         Topo_Diff may represent invalid operations, eg. adding a link while
#          removing it's end-point - this stub should check for that
#         """
#         pass


# Path: rhizi/tools/rz_doc.py
import argparse  # TODO - use the newer / shorter argument parser. y?
import json
import os
import sys
import uuid
from collections import namedtuple
from ..model.graph import Topo_Diff
from ..rz_file import RZFile
from .. import rz


    Missing:
        this loses all the history.
        no user recorded for newly created doc
    """
    global kernel
    destination = kernel.rzdoc__create(rzdoc_name)
    ctx = namedtuple('Context', ['user_name', 'rzdoc'])(None, destination)
    kernel.diff_commit__topo(clone, ctx)


def names():
    global kernel
    return [v['name'] for v in kernel.rzdoc__list()]


def create_id():
    return uuid.uuid4().get_hex()[:8]


def merge_topos(topos, names):
    """
    Merge a number of Topo_Diff's

    result node set is union of nodes
    conflicting nodes:
        same name nodes take the first (id wise)
        attributes: take the first
    result link set is merged (well defined: replace dropped id by chosen id in all links)
    """

    result = Topo_Diff()