from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.dialects.postgresql import ARRAY, JSONB
from sqlalchemy import Column, Text, DateTime, BigInteger, text, Index
from copy import copy


Base = declarative_base()


class VersionedNode(Base):

    __tablename__ = 'versioned_nodes'
    __table_args__ = (
        Index('submitted_node_id_idx', 'node_id'),
        Index('submitted_node_gdc_versions_idx', 'node_id'),
    )

    def __repr__(self):
        return ("<VersionedNode(key={}, label='{}', node_id='{}')>"
                .format(self.key, self.label, self.node_id))

    key = Column(
        BigInteger,
        primary_key=True,
        nullable=False
    )

    label = Column(
        Text,
        nullable=False,
    )

    node_id = Column(
        Text,
        nullable=False,
    )

    project_id = Column(
        Text,
        nullable=False,
    )

    gdc_versions = Column(
        ARRAY(Text),
    )

    created = Column(
        DateTime(timezone=True),
        nullable=False,
    )

    versioned = Column(
        DateTime(timezone=True),
        nullable=False,
        server_default=text('now()'),
    )

    acl = Column(
        ARRAY(Text),
        default=list(),
    )

    system_annotations = Column(
        JSONB,
        default={},
    )

    properties = Column(
        JSONB,
        default={},
    )

    neighbors = Column(
        ARRAY(Text),
    )

    @staticmethod
    def clone(node):
        return VersionedNode(
            label=copy(node.label),
            node_id=copy(node.node_id),
            project_id=copy(node._props.get('project_id')),
            created=copy(node.created),
            acl=copy(node.acl),
            system_annotations=copy(node.system_annotations),
            properties=copy(node.properties),
            neighbors=copy([
                edge.dst_id for edge in node.edges_out
            ] + [
                edge.src_id for edge in node.edges_in
            ])
        )
